zoukankan      html  css  js  c++  java
  • Linux : perror、exit、_exit、wait 和 waitpid

    perror:
      #include<stdio.h>   
           #include<stdlib.h>

    函数定义

      void perror(const char *s);  perror ("open_port");

    函数说明

      perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 错误 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量error 的值来决定要输出的字符串。   
           在库函数中有个error变量,每个error值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了error的值。perror函数只是将你输入的一些信息和现在的error所对应的错误一起输出。

    exit:(#include <stdlib.h>)
        在C语言的main函数中我们通常使用return (0);这样的方式返回一个值。但这是限定在非void情况下的,也就是非void main()这样的形式。exit()通常是用在子程序中用来终结程序用的,使用后程序自动结束,跳出操作系统。   
        exit(0) 表示程序正常退出,
        exit(1)/exit(-1)表示程序异常退出。
     exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束。
     但在如果把exit用在main内的时候无论main是否定义成void返回的值都是有效的,并且exit不需要考虑类型,exit(1)等价于return (1) 。   
    例如:   
    #include<stdlib.h>   
    int main()   
    {
       exit (1);//等价于return (1);   
    }
      exit()是一个函数 ,结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程,在父进程中wait系统调用将接受到此返回信息。

    进程就好比人一样有其生命,我们通过fork()函数来创建一个进程,那么我们又是如何来中止进程呢。

    进程退出

    1.在Linux中如何让一个进程退出

    进程退出表示进程即将结束。在Linux中进程退出分为了正常退出和异常退出两种。

    1>正常退出

    a. 在main()函数中执行return 。

    b.调用exit()函数   #include <stdlib.h>    void exit(int status)

    c.调用_exit()函数   #include <unistd.h>   void _exit(int status)

    status 是一个整型的参数,可以利用这个参数传递进程结束时的状态。一般来说,
    0 表示正常结束;其他的数值表示出现了错误,进程非正常结束。
    在实际编程时,可以用 wait 系统调用接收子进程的返回值,从而针对不同的情况
    进行不同的处理

    2>异常退出

    a.调用about函数

    b.进程收到某个信号,而该信号使程序终止。


    Tiger-John说明:
    不管 是那种 退出方式,系统最终都会执行内核中的同一代码。这段代码用来关闭进程所用已打开的文件描述符,释放它所占用的内存和其他资源。

    3>比较以上几种退出方式的不同点

    (1)exit和return 的区别:

    a.exit是一个函数,有参数。exit执行完后把控制权交给系统

    b.return是函数执行完后的返回。renturn执行完后把控制权交给调用函数。

    (2)exit和abort的区别:

    a.exit是正常终止进程

    b.about是异常终止。

    现在我们重点了解exit()和_exit()函数

    exit()和_exit()

    1>exit和_exit函数都是用来终止进程的。

    当程序执行到exit或_exit时,系统无条件的停止剩下所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。

    2>exit在头文件stdlib.h中声明,而_exit()声明在头文件unistd.h中声明。 exit中的参数exit_code为0代表进程正常终止,若为其他值表示程序执行过程中有错误发生。

    3>exit()和_exit()的区别:


    a._exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。

    b. 调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin, stdout, stderr  ...).   exit函数是在_exit函数之上的一个封装,其会调用_exit,并在调用之前先刷新流。

    Tiger-John说明:

    exit()函数与_exit()函数最大区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区的内容写回文件。 由于Linux的标准函数库中,有一种被称作“缓冲I/O”的 操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续的读 出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区读取;同样,每次写文件的时候也仅仅是写入内存的缓冲区,等满足了一定的条件(如达到了一定数 量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度,但也给编程代来了一点儿麻烦。比如有一些数据,认为已经写 入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时用_exit()函数直接将进程关闭,缓冲区的数据就会丢失。因此,要想保证数 据的完整性,就一定要使用exit()函数。

    c . 通过一个函数实例来看看它们之间的区别:

    函数实例1 : exit.c

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3
     4 int main()
     5 {
     6         printf("using exit---- ");
     7         printf("This is the content in buffer ");
     8         exit(0);
    9 }

    函数经过调试后

    $ gcc exit.c -o exit
    $ ./exit


    执行结果为:

    using exit----
    This is the content in buffer

    函数实例2:_exit.c

     1 #include<stdio.h>
     2 #include<unistd.h>
     3
     4 int main(void)
     5 {
     6         printf("using _exit-- ");
     7         printf("This is the content in buffer");
     8         _exit(0);
     9 }
      函数经过调试后

    $ gcc _exit.c -o _exit
    $ ./_exit


    执行结果为 :

    using _exit--


    Tiger-John说明:

    1.printf函数就是使用缓冲I/O的方式,该函数在遇到“ ”换行符时自动的从缓冲区中将记录读出。所以exit()将缓冲区的数据写完后才退出,而_exit()函数直接退出。

    2. 大家也可以把函数实例2中的printf("This is the content in buffer");改为printf("This is the content in buffer ")(即在printf中最后加一个 看运行结果是什么,为什么会产生这样的结果呢?)

    小知识

    在一个进程调用了 exit 之后,该进程并不马上就完全消失,而是留下一个称为僵尸进程
    (Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它几乎已经放弃了所有内存空间,
    没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出
    状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。

    wait
          wait 函数是用于使父进程(也就是调用 wait 的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。
    如果该父进程没有子进程或者他的子进程已经结束, wait则就会立即返回。
    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t wait(int *status)


    waitpid
          waitpid 的作用和 wait 一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的 wait 功能,也能支持作业控制。实际上 wait 函数只是 waitpid 函数的一个特例,在 Linux 内部实现 wait 函数时直接调用的就是 waitpid 函数。
    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t waitpid(pid_t pid, int *status, int options)

  • 相关阅读:
    什么是“开放构造类型”,“封闭构造类型”
    代码整洁整洁之道读书笔记 2
    学习 WCF By Visual Studio 2010 (1)起步“全双工”
    代码整洁整洁之道读书笔记 1
    学习 WCF By Visual Studio 2010 (2) 宿主
    持久层通用组件设计与范例,写给某孩子(基于JDBC)
    [zz]JS后退一页, JS返回上一页代码, JS返回下一页,JS返回第几页,JS页面跳转, JS引用JS
    web下vs2008+crystal report 不预览直接打印
    用SQL语句删除重复记录
    Gridview 添加行.
  • 原文地址:https://www.cnblogs.com/huazhen/p/3424684.html
Copyright © 2011-2022 走看看