waitpid()错误问题

6 fork wait

我编写代码来按顺序打印pidparent->g3->c2->g1->g2->c1.

所以我用过wait(),和waitpid().但我失败了.

所以我写了"完成"代码来了解什么是问题.

而且我知道c1忽略了waitpid并打印了what-> finish.

我怎么解决这个问题


#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

void main()
{
pid_t c1,c2,g1,g2,g3;

printf("parent:%d\n", (int)getpid());
c1=fork();
int status;
if (c1>0) {
        c2=fork();
        if (c2==0) {
            g3=fork();
            if (g3==0) {
                    printf("g3:%d\n",(int)getpid());
            } else if (g3>0) {
            wait(&status);
            printf("c2:%d\n",(int)getpid());
            }
       }
} else if (c1==0) {
        waitpid(c2,&status,WUNTRACED);
    printf("what\n");
    g1=fork();
    if (g1>0) {
            g2=fork();
            if (g2==0) {
                printf("g2:%d\n",(int)getpid());
            } else if (g2>0) {
                    waitpid(g1,&status,WUNTRACED);
                    printf("c1:%d\n", (int)getpid());
            }
        } else if (g1==0) {
            waitpid(g2,&status,WUNTRACED);
            printf("g1:%d\n",(int)getpid());
            } else {
                printf("failed\n");
                exit(1);
            }
} else {
    printf("main failed\n");
    exit(1);
} printf("finish\n");
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Prv*_*dav 1

我验证了这段代码gcc 6.3.0,它在那里工作正常。这段代码按照您询问的顺序打印它们:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>

static int *glob_var;

int main()
{
int c1,c2,g1,g2,g3;
glob_var = mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE, 
                MAP_SHARED | MAP_ANONYMOUS, -1, 0);
printf("parent:%d\n", (int)getpid());
*glob_var = 0;
c1=fork();
int status;
if (c1>0) {
        c2=fork();
        if (c2==0) {
            g3=fork();
            if (g3==0) {
                printf("g3:%d\n",(int)getpid());
            } else if (g3>0) {
            wait(&status);
            printf("c2:%d\n",(int)getpid());
            *glob_var = 1;
            }
   }
} else if (c1==0) {
       while(*glob_var == 0);

    printf("what\n");
    g1=fork();
    if (g1>0) {
        waitpid(g1,&status,WUNTRACED);
        g2=fork();

        if (g2==0) {

            printf("g2:%d\n",(int)getpid());
        } else if (g2>0) {
                waitpid(g2,&status,WUNTRACED);
                printf("c1:%d\n", (int)getpid());
        }
    } else if (g1==0) {

        printf("g1:%d\n",(int)getpid());
        } else {
            printf("failed\n");
            exit(1);
        }
} else {
    printf("main failed\n");
    exit(1);
}

}
Run Code Online (Sandbox Code Playgroud)

我做了一些chagnes。

我刚刚waitpid(g2,&status,WUNTRACED);在开头添加

 else if (g2>0) {
            waitpid(g2,&status,WUNTRACED);
            printf("c1:%d\n", (int)getpid());
    } 
Run Code Online (Sandbox Code Playgroud)

条件语句,因此 g2 将在 c1 之前完成。

waitpid(g1,&status,WUNTRACED);在条件语句中添加,if(g1>0)以便 g1 将在 g2 之前完成。

我还使用了一个glob_var全局变量,声明为static int *glob_var;并用于mmap在父子之间共享它。

 glob_var = mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE, 
            MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Run Code Online (Sandbox Code Playgroud)

并使用它作为信号量来执行c2之前c1,它的工作方式就像当 c2 完成时它将信号量的值从0 更改为 1,之后只有while(*glob_var == 0)循环将else if(c1==0)继续中断条件。

而且也不需要,waitpid(c2,&status,WUNTRACED);所以else if (c1==0)我把它删除了。