Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems in code with multiple child creation

This code is part of my OS project, the project asks to make something where apply concurrent processes, I decided to make a client server poker project with two players where I use sons and grandson processes to determinate the hand value.

The scheme applied in the code is the follow:

1

The problem with the code is that in the same game only the first hand is correctly evaluated, infact the second is incorrect and in the third game there is an error and the program ends, this happens for every new game

Here's the code:

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);
}

In the following code I put some Checkpoint to find the bug, the result during execution is for every new game the same for both player 1 and player 2:

1 hand (always correct)

 checkpoint A
 checkpoint B
 point=value

2 hand

 checkpoint A
 point=value
 checkpoint B

why this happen? The father has to wait for its son and in this case he doesn't wait

3 hand

point=-1
and exit

Thanks in advance.

like image 1000
abc Avatar asked Jan 25 '13 18:01

abc


1 Answers

I got this strong feeling that your troubles are related to your last wait loop. You are only waiting twice for child processes. No matter if the returned PID is one of the chidren you are checking.

My guess is that your grandchildren are causing wait to return or a value <-1 is returned for what ever reason

The prove would be to place an else-clause in your wait-loop outputting the PID and check this PID with the PIDs of created processes.

What I'd do anyway is to change your wait loop to only increment j if one of the two sons triggered the return of the waitcall.

like image 124
junix Avatar answered Nov 07 '22 17:11

junix