Waitpid 就像在非阻塞模式下一样
Waitpid acting as if in non-blocking mode
我正在使用 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秒!)
编辑:我在 execvp 下面添加了 printf("Here")
和 exit(1)
,并按照评论中的建议打印出 waitpid 的输出。这里没有打印,waitpid 打印 -1
问题是竞争条件。在这里分叉后:
a = fork();
如果 child 运行 首先在此处创建进程组 -a
:
if(a==0){
setpgid(getpid(),getpid());
然后 parent 在这里等待:
waitpid(-a,&t2,0);
但是如果 parent 首先到达 运行,则进程组 -a
不会 还存在并且 waitpid()
失败并返回 ECHILD
。第二种情况显然发生在您的系统上。
您必须找到一些方法来确保 setpgid()
在 child 运行 之前 waitpid()
在 parent 中调用。复杂的方式是信号量,简单的(hacky)方式是短暂的延迟,waitpid()
之前的 usleep(1)
可能就足够了。
我正在使用 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秒!)
编辑:我在 execvp 下面添加了 printf("Here")
和 exit(1)
,并按照评论中的建议打印出 waitpid 的输出。这里没有打印,waitpid 打印 -1
问题是竞争条件。在这里分叉后:
a = fork();
如果 child 运行 首先在此处创建进程组 -a
:
if(a==0){
setpgid(getpid(),getpid());
然后 parent 在这里等待:
waitpid(-a,&t2,0);
但是如果 parent 首先到达 运行,则进程组 -a
不会 还存在并且 waitpid()
失败并返回 ECHILD
。第二种情况显然发生在您的系统上。
您必须找到一些方法来确保 setpgid()
在 child 运行 之前 waitpid()
在 parent 中调用。复杂的方式是信号量,简单的(hacky)方式是短暂的延迟,waitpid()
之前的 usleep(1)
可能就足够了。