c - Waitpid 的行为就像处于非阻塞模式

标签 c operating-system system-calls pid waitpid

我正在使用 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

最佳答案

问题是竞争条件。在这里 fork 之后:

a = fork();

如果子进程首先运行,则在此处创建进程组-a:

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

然后家长在这里等待:

waitpid(-a,&t2,0);

但是如果父进程先运行,进程组-a确实存在,并且waitpid() 失败,并显示 ECHILD。第二种情况显然发生在您的系统上。

您必须找到某种方法来确保子进程中的setpgid()调用在waitpid()之前运行叫来家长。复杂的方法是信号量,简单(hacky)的方法是短暂的延迟,在 waitpid() 之前的 usleep(1) 可能就足够了。

关于c - Waitpid 的行为就像处于非阻塞模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54550459/

相关文章:

c++ - 在 C++ 中分隔字符串

c - 为什么编译器不从函数定义中推断出函数原型(prototype)?

c - 零线程进程?

java - java中的synchronized关键字是如何实现的?

audio - 获取MP3音频压缩库

memory-management - Intel x86-64 CPU 访问多少页表来转换虚拟内存?

linux - 从 perl 执行挂载系统调用

c - 明智地读取文件元素

c - 使用 C 访问 xml 中的数据

c - 在 OSX 10.12 上使用 mmap() 时出现 'cannot allocate memory' 错误