waitpid()错误问题

时间:2018-10-07 05:03:45

标签: fork wait

我写了代码以按parent->g3->c2->g1->g2->c1的顺序打印 pid

因此,我使用了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");
}

enter image description here

2 个答案:

答案 0 :(得分:2)

pid_t c1,c2,g1,g2,g3;

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

从未设置c2变量,因此它可能包含碰巧在堆栈上的所有垃圾。如果使用-Wall标志运行它,编译器会警告您。

此外,您应该始终检查waitpid的返回值;那也将捕获该错误。

fork之后,不要假设孩子将被安排在父对象之前运行,反之亦然。

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

与上述相同,g2变量无需初始化即可使用。

另外,main的返回值应该是int,而不是void

并且您应该始终使用-O2 -Wextra -Wall标志进行编译,这将为您节省很多麻烦。如果发现多余的警告,可以分别将其关闭。例如。 (-Wno-parentheses-Wno-unused)。

答案 1 :(得分: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);
}

}

我没做过香糖。

我刚刚在{p>的开头添加了waitpid(g2,&status,WUNTRACED);

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

条件语句,因此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);

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

waitpid(c2,&status,WUNTRACED);中也不需要else if (c1==0),所以我将其删除。