我正在玩C语言中的系统调用,并且一直试图了解我编写的这个程序-
int main(int argc, char* argv[])
{
int a;
char *args[]={"sleep"," 10",NULL};
a = fork();
int stat;
if(a==0){
setpgid(getpid(),getpid());
printf("%d\n",getpgid(getpid()));
execvp(args[0],args);}
else
{
int t2;
waitpid(-a,&t2,0);
}
printf("Parent pid = %d\n", getpid());
printf("Child pid = %d\n", a);
}
根据我的理解,我将child的pgid设置为其自己的pid。当我以-a作为参数调用waitpid
时,我基本上是在等待pgid = a中的任何过程完成为止。但是,程序的输出不是我期望的!子进程根本没有收获。好像waitpid处于非阻塞模式。输出:
Parent pid = 11372
Child pid = 11373
11373
(输出是瞬时的,它不会等待10秒!)
EDIT:我在execvp下面添加了printf("Here")
和exit(1)
并按照注释中的建议打印出了waitpid的输出。这里没有打印,waitpid打印为-1
答案 0 :(得分:2)
问题是竞赛状况。在前叉之后:
a = fork();
如果孩子首先运行,则在此处创建进程组-a
:
if(a==0){
setpgid(getpid(),getpid());
然后父母在这里等待:
waitpid(-a,&t2,0);
但是如果 parent 首先运行,则进程组-a
尚不存在,并且waitpid()
失败,{{1 }}。第二种情况显然发生在您的系统上。
您将必须找到某种方法来确保子代中的ECHILD
调用在父代中的setpgid()
调用之前运行。复杂的方法是信号量,简单的(hacky)方法是一个短暂的延迟,在waitpid()
之前就可以usleep(1)
。