2016-11-19 14:15:01 Move_now 阅读数 529

wait()函数

所需头文件:#include <sys/types.h> #include<sys/wait.h>
函数原型:pid_t wait(int *status)
作用:wait()函数会暂停当前进程的执行,直到有子进程的结束,此时wait()函数会返回子进程结束状态值,由status接收,如果对这个子进程是如何结束的并不关心,那么这个参数也可以设为NULL。如果执行成功会返回子进程的PID,有错返回-1。
例子:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
    pid_t pid;
    pid = fork();
    if(pid == (pid_t)0) //如果是子进程
    {
        printf("this is the child process!\n");
        sleep(5);  //等待5秒
    }
    else
    {
        wait(NULL); 
        printf("this is the father process!\n");
    }   
    return 0;
}  

输出结果:

this is the child process!  
this is the father process!  

运行这段代码会得到这样的结果,但是可以发现,第二个输出this is the father process!,会等待5秒再输出。这是因为wait()函数会等待子进程的结束当前进程再继续进行,否则当前进程一直处于堵塞状态。当我们调用fork()函数,成功地拷贝出来另一个子进程时,父子进程会各自完成各自的代码,当父进程遇到wait()函数时,会处于堵塞状态,等待子进程的结束才继续向下执行。

waitpid()函数

所需头文件:#include <sys/types.h> #include <sys/wait.h>
函数原型:pid_t waitpid(pid_t pid, int *status, int options)
作用: 作用和wait()函数类似,只是多了两个参数pidoptionspid参数的含义是传入想要等待结束的子进程识别码,options参数可以进行一些特殊的处理,可以填0表示没有选项,多个选项之间可以用或(|)隔开。如果执行成功则返回子进程的PID, 如果有错误发生则返回-1,另外如果设置了WNOHANG参数,没有结束的子进程的话就返回0。
有以下这4种pid:

  1. pid<-1 等待指定进程组ID为pid的绝对值的任何子进程.
  2. pid=-1 等待任何子进程, 相当于wait().
  3. pid=0 等待同一进程组的任何子进程.
  4. pid>0 等待任何子进程识别码为pid 的子进程,比如传进去的pid值是3000,那么只有当pid值为3000的子进程结束了,当前进程才能继续执行

有以下8种options:

  1. WNOHANG:如果没有任何已经结束的子进程则马上返回, 不予以等待.
  2. WUNTRACED:如果子进程进入暂停执行情况则马上返回, 但结束状态不予以理会.
  3. WIFEXITED(status):如果子进程正常结束则赋值为非0值.
  4. WEXITSTATUS(status):取得子进程exit()返回的结束代码, 一般会先用WIFEXITED 来判断是否正常结束才能使用此宏.
  5. WIFSIGNALED(status):如果子进程是因为信号而结束则此宏值为真
  6. WTERMSIG(status):取得子进程因信号而中止的信号代码, 一般会先用WIFSIGNALED 来判断后才使用此宏.
  7. WIFSTOPPED(status):如果子进程处于暂停执行情况则此宏值为真. 一般只有使用WUNTRACED时才会有此情况.
  8. WSTOPSIG(status):取得引发子进程暂停的信号代码, 一般会先用WIFSTOPPED 来判断后才使用此宏.

例子:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
    pid_t pid;
    pid = fork();
    if(pid == (pid_t)0) //如果是子进程
    {
        printf("this is the child process!\n");
        sleep(5);
    }
    else
    {
        int temp = 0;
        while(temp==0)  //除非子进程结束,否则一直循环
        {
            if((temp = waitpid(pid, NULL, WNOHANG))!=0)  //只有当子进程结束时,返回值才不为0
                printf("this is the father process!\n");
            else
                printf("the child process is not exited\n");
        }   
    }
    return 0;
}  

输出结果:

this is the child process!
the child process is not exited  
the child process is not exited
the child process is not exited
.....                           //这里有很多个输出,省略了
the child process is not exited
the child process is not exited
the child process is not exited
this is the father process!

可见我们设置了WNOHANG参数时,每次父进程执行waitpid()函数,发现子进程没结束,不用等待子进程结束而继续执行,此时返回值为0,继续执行循环,直到子进程结束。其它参数感兴趣的可以自己试一试。

2012-06-06 14:09:55 pianpianboy 阅读数 450

作者:pianpianboy
出处:翩翩男孩blog


前言:

   本文只是自己在读《unix环境高级编程》时的一些感悟,加上本人初涉计算机领域,水平有限,如有不对的地方希望大家指正!  

wait 和waitpid:

一、定义?

      #include <sys/wait.h>

      pid_t wait( int *statloc);

      pid_t waitpid( pid_t pid ,int  *statloc, int options);

  1. 参数statloc 是一个整型指针,如果statloc为空(即wait( NULL))则不保存进程结束的终止状态;如果statloc 不为空,则将终止进程的终止状态将保存在statloc指向的单元(结构或者文件)内。
  2. 参数pid:  
  • pid ==-1(此时waitpid 和wait 的功能相同,等待任一进程);
  • pid  > 0(此时waitpid函数等待进程ID 和pid相等的子进程);
  • pid ==0 (此时waitpid函数等待其组ID和调用进程的组ID相等的子进程);
  • pid < 0 (此时waitpid函数等待其组ID的绝对值和调用进程组ID相等的子进程);
  • 参数options:为进一步的提供更多的操作,主要是实现对支持实现作业的控制;
   3.二个函数的返回值:子进程ID;

二、为什么要使用wait和waitpid这个函数?

  首先介绍下僵死进程:一个已经终止,但是其父进程未对其进行后续处理(获得其终止子进程的相关信息,释放它仍然占用的资源)的进程。为了防止系统中有很多的僵死进程,unix中系统调用wait或waitpid 来获得终止子进程的终止状态,返回给其父进程,以便父进程做相应的善后处理(这样可以防止产生很多的僵死进程);如果子进程是孤儿进程,或者说父进程是init,那么当子进程终止时,init 便会立即调用wait函数获取其终止状态,这也是为了避免产生僵死进程而使用二次fork的原因(让子进程的父进程先终止后,被init收养)。

三、调用wait和waitpid函数的进程会出现的情况?   

  1. 如果所有的子进程都在运行,则该进程阻塞; 
  2. 如果一个子进程已经终止,正在等待其父进程获取其终止状态,则该进程取得子进程的终止状态后立即返回;
  3. 如果它没有任何子进程,则返回出错;

四、wait 和 waitpid 之间的区别?

  1. 在一个子进程终止前调用wait函数会使其调用进程阻塞,而waitpid 函数会通过设置其参数options(WNOHANG),是调用进程不阻塞。
  2. waitpid可以通过其参数pid,控制其等待子进程。waitpid支持作业操作。

2011-03-30 17:02:00 jpcfei 阅读数 1123

wait的函数原型是:  

#include<sys/types.h>

#include <sys/wait.h>


pid_t wait(int *status)     

      进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。    

      参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为

NULL,就象下面这样:

      pid = wait(NULL);

      如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被

置为ECHILD。 

 

waitpid的函数原型是:   

waitpid系统调用在Linux函数库中的原型是:   

#include <sys/types.h>

#include <sys/wait.h>


pid_t waitpid(pid_t pid,int *status,int options)

      从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。

下面我们就来详细介绍一下这两个参数:     

● pid     从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。   

● options   options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用,比如:ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);   如果我们不想使用它们,也可以把options设为0,如:   ret=waitpid(-1,NULL,0);     如果使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。     而WUNTRACED参数,由于涉及到一些跟踪调试方面的知识,加之极少用到,这里就不多费笔墨了,有兴趣的读者可以自行查阅相关材料。    看到这里,聪明的读者可能已经看出端倪了--wait不就是经过包装的waitpid吗?没错,察看<内核源码目录>/include/unistd.h文件349-352行就会发现以下程序段:

     static inline pid_t wait(int * wait_stat)   

             {

         return waitpid(-1,wait_stat,0);

         }      

返回值和错误waitpid的返回值比wait稍微复杂一些,一共有3种情况:  

● 当正常返回的时候,waitpid返回收集到的子进程的进程ID;

● 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;      

● 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD 其它: 调用 wait&waitpid 来处理终止的子进程: pid_t wait(int * statloc); pid_t waitpid(pid_t pid, int *statloc, int options); 两个函数都返回两个值:函数的返回值和终止的子进程ID,而子进程终止的状态则是通过statloc指针返回的。 wait&waitpid 的区别是显而易见的,wait等待第一个终止的子进程,而waitpid则可以指定等待特定的子进程。这样的区别可能会在下面这种情况时表现得更加明显:当同时有5个客户连上服务器,也就是说有五个子进程分别对应了5个客户,此时,五个客户几乎在同时请求终止,这样一来,几乎同时,五个FIN发向服务器,同样的,五个SIGCHLD信号到达服务器,然而,UNIX的信号往往是不会排队的,显然这样一来,信号处理函数将只会执行一次,残留剩余四个子进程作为僵尸进程驻留在内核空间。此时,正确的解决办法是利用waitpid(-1, &stat, WNOHANG)防止留下僵尸进程。其中的pid为-1表明等待第一个终止的子进程,而WNOHANG选择项通知内核在没有已终止进程项时不要阻塞。wait&waitpid 区别 :waitpid提供了wait函数不能实现的3个功能: waitpid等待特定的子进程, 而wait则返回任一终止状态的子进程; waitpid提供了一个wait的非阻塞版本; waitpid支持作业控制(以WUNTRACED选项). 用于检查wait和waitpid两个函数返回终止状态的宏: 这两个函数返回的子进程状态都保存在statloc指针中, 用以下3个宏可以检查该状态: WIFEXITED(status): 若为正常终止, 则为真. 此时可执行 WEXITSTATUS(status): 取子进程传送给exit或_exit参数的低8位. WIFSIGNALED(status): 若为异常终止, 则为真. 此时可执行 WTERMSIG(status): 取使子进程终止的信号编号.WIFSTOPPED(status): 若为当前暂停子进程, 则为真. 此时可执行 WSTOPSIG(status): 取使子进程暂停的信号编号

2019-05-10 20:43:14 hello_ape 阅读数 34

 两个函数的原型如下:

 #include <sys/types.h>
 #include <sys/wait.h>

 pid_t wait(int *status);

 pid_t waitpid(pid_t pid, int *status, int options);

可以通过status获取子进程的退出状态,如果不关心,可以将status置为NULL

 

对于waitpid函数,pid参数可以设置为以下任意值:

<-1 回收进程组id等于pid绝对值的任意子进程

-1  回收任意的子进程

0   回收进程组id等于调用进程的任意进程

>0 回收等于pid的子进程

 

options参数可以设置为以下值:

WNOHANG       

WUNTRACED     

WCONTINUED    

函数成功调用返回进程id,如果失败返回0或者-1

 

wait和waitpid的区别有以下几点:

1、wait会使调用者阻塞,即父进程会阻塞在wait调用上。而waitpid可选非阻塞方式。

2、当有子进程结束时,wait调用就返回。如果父进程产生了多个子进程,如果使用wait意味着父进程无法指定具体回收某一个子进程。waitpid参数中,可以指定回收某一个特定的子进程。

 

2019-10-27 13:23:00 LQXFYYY 阅读数 23

wait(NULL):父进程等待子进程
踩坑
1.怎么输入一个指针数组,并且以回车结束最后一个输入
2.没有new,没有cin,linux风格
3.linux不支持gets,只支持fgets,scanf
4.调用wait要加<sys/wait.h>
输入参数理解错意思了,并非是一条命令的参数,而是所有命令的条数

exec()

没有更多推荐了,返回首页