具有多个子创建的代码中的问题

abc*_*abc 7 c fork multiple-processes

这段代码是我的操作系统项目的一部分,项目要求做一些应用并发进程的东西,我决定用两个玩家做一个客户服务器扑克项目,我用儿子和孙子进程来确定手牌价值.

代码中应用的方案如下:

1 http://f.cl.ly/items/2f3x3z1A3z1n3r2b0X0N/schema.jpg

代码的问题在于,在同一游戏中只有第一只手被正确评估,实际上第二只手是不正确的,而在第三局游戏中有错误并且程序结束,这发生在每一个新游戏中

这是代码:

void check_hand(int suits[5],int ranks[5],int *point){

    pid_t son[2];
    int i,j;

    for (i = 0; i < 2; i++){
            son[i]=fork();

    /***********************************************
            straight flush son
    ************************************************/

            if(son[i]==0 && i==0){
                    pid_t grandson[3];
                    int k;
                    for(k=0;k<3;k++){
                            grandson[k]=fork();
                            if(grandson[k]==0 && k==0){
                                    exit(F_highcard(ranks));
                            }
                            else if(grandson[k]==0 && k==1){
                                    exit(F_flush(suits));
                            }
                            else if(grandson[k]==0 && k==2){
                                    exit(F_straight(ranks));
                            }
                            else if(grandson[k]<0){
                                    puts("fork failed");
                                    exit(-1);
                            }
                    }
                    int exit_status_straight,exit_status_flush,exit_status_highcard;
                    //waiting his sons
                    waitpid(grandson[0],&exit_status_highcard,0);
                    waitpid(grandson[1],&exit_status_flush,0);
                    waitpid(grandson[2],&exit_status_straight,0);

                    /**checkpoint A****/

                    //elaborate the exit statuses and exit with a value
            }

    /***********************************************
                    full house son
    ************************************************/


            if(son[i]==0 && i==1){
                    pid_t grandson[2];
                    int k;
                    for(k=0;k<2;k++){
                            grandson[k]=fork();
                            if(grandson[k]==0 && k==0){
                                    exit(F_n_pairs(ranks));
                            }
                            else if(grandson[k]==0 && k==1){
                                    exit(F_tris_poker(ranks));
                            }
                            else if(grandson[k]<0){
                                    exit(-1);
                            }
                    }

                    int exit_status_pair,exit_status_tris_or_poker;
                    waitpid(grandson[0],&exit_status_pair,0);
                    waitpid(grandson[1],&exit_status_tris_or_poker,0);

                    /**checkpoint B****/

                    //elaborate the exit statuses and exit with a value
                    }
            }
            if(son[i]<0){
                    puts("fork failed");
                    exit(-1);
            }
    }

    /***********************************************
            analysis exit status of his 2 sons
    ************************************************/
    pid_t pid;
    int status;
    int values[10];
    //initialization
    for(j=0;j<10;j++)values[j]=0;

    for(j=0;j<2;j++ ){
            pid = wait(&status);
            if(pid==son[0]){
                    values[WEXITSTATUS(status)]=1;
            }
            else if(pid==son[1]){
                    values[WEXITSTATUS(status)]=1;
            }
            else if(pid==-1){
                    puts("error");
                    exit(1);
            }
    }

    for(j=9;j>=0;j--){
            if(values[j]==1)break;
    }
    *point=j;
    printf("point=%d\n",*point);
}
Run Code Online (Sandbox Code Playgroud)

在下面的代码中我放了一些Checkpoint来查找bug,执行期间的结果是每个新游戏对于玩家1和玩家2都是一样的:

1手(始终正确)

 checkpoint A
 checkpoint B
 point=value
Run Code Online (Sandbox Code Playgroud)

2手

 checkpoint A
 point=value
 checkpoint B
Run Code Online (Sandbox Code Playgroud)

为什么会这样?父亲必须等待它的儿子,在这种情况下,他不会等待

3手

point=-1
and exit
Run Code Online (Sandbox Code Playgroud)

提前致谢.

jun*_*nix 1

我有一种强烈的感觉,你的麻烦与你最后的等待循环有关。您只需要等待子进程两次。无论返回的 PID 是否是您正在检查的子进程之一。

我的猜测是您的孙子正在等待返回或由于某种原因返回 <-1 的值

证明是在输出 PID 的等待循环中放置一个 else 子句,并使用创建的进程的 PID 检查该 PID。

无论如何,我要做的就是将等待循环更改为仅在两个儿子之一触发呼叫返回时才增加 j wait