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:
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.
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 wait
call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With