简体   繁体   English

Waitpid就像在非阻塞模式下一样

[英]Waitpid acting as if in non-blocking mode

I am playing around with system calls in C and I am stuck trying to understand this program I made - 我正在玩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); 

}

According to my understanding, I have set pgid of child as its own pid. 根据我的理解,我将child的pgid设置为其自己的pid。 When I call waitpid with -a as argument, I am basically asking it to wait(blocking) till any process in pgid=a is finished. 当我使用-a作为参数调用waitpid时,我基本上是在等待pgid = a中的任何进程完成之前进行等待(阻塞)。 However, the output of the program is not what I expected! 但是,程序的输出不是我期望的! Child process isn't being reaped at all. 子进程根本没有收获。 It is as if waitpid is in non-blocking mode. 好像waitpid处于非阻塞模式。 Output: 输出:

Parent pid = 11372
Child pid = 11373
11373

(The output is instantaneous, it doesn't wait for 10 seconds!) (输出是瞬时的,它不会等待10秒!)

EDIT : I added printf("Here") and exit(1) below execvp and printed out waitpid's output as suggested in comments. 编辑:我在execvp printf("Here")添加了printf("Here")exit(1) ,并按照注释中的建议打印出了waitpid的输出。 Here doesn't get printed and waitpid prints -1 这里不打印,waitpid打印-1

The problem is a race condition. 问题是比赛条件。 After the fork here: 后叉在这里:

a = fork();

if the child runs first the process group -a is created here: 如果子级先运行,则在此处创建进程组-a

if(a==0){
    setpgid(getpid(),getpid());

and the parent then waits here: 然后父母在这里等待:

waitpid(-a,&t2,0);

but if the parent gets to run first, the process group -a does not exist yet and the waitpid() fails with ECHILD . 但是,如果父级先运行,则进程组-a 尚不存在,并且waitpid()失败并显示ECHILD The second case obviously happens on your system. 第二种情况显然发生在您的系统上。

You will have to find some way to make sure, that the setpgid() call in the child runs before the waitpid() call in the parent. 您将必须找到某种方法来确保子级中的setpgid()调用在父级中的waitpid()调用之前运行。 The complex way are semaphores, the easy (hacky) way is a short delay, usleep(1) before the waitpid() will probably suffice. 复杂的方法是信号量,简单的(hacky)方法是短暂的延迟,在waitpid()可能就足够之前使用usleep(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM