【发布时间】:2013-01-25 18:12:48
【问题描述】:
此代码是我的操作系统项目的一部分,该项目要求在应用并发进程的情况下制作一些东西,我决定制作一个有两个玩家的客户端服务器扑克项目,我使用儿子和孙子进程来确定手牌价值。
代码中应用的方案如下:
代码的问题是,在同一个游戏中,只有第一手被正确评估,实际上第二个是不正确的,在第三个游戏中出现错误并且程序结束,这对于每个新游戏都会发生
代码如下:
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);
}
在下面的代码中,我放置了一些检查点来查找错误,执行期间的结果对于玩家 1 和玩家 2 的每个新游戏都是相同的:
1 手(始终正确)
checkpoint A
checkpoint B
point=value
2手
checkpoint A
point=value
checkpoint B
为什么会这样?父亲必须等待儿子,在这种情况下他不等待
3手
point=-1
and exit
提前致谢。
【问题讨论】:
-
当您执行
fork()时,您创建了一个新进程,而这些进程看不到对彼此内存所做的更改。看起来您的算法是为共享内存设计的,但为此您需要使用线程。 -
“进程看不到对彼此的内存所做的更改”是什么意思?子进程和孙子进程不做任何改变,他们只是检查是否有一个点并退出一个值,然后父亲结合其儿子的退出值的结果,即在退出之前已经结合了他们儿子的退出状态.
-
好的,我明白你的意思了。在我看来,您正在尝试读取共享内存,但如果您只是与退出状态进行通信,那应该没问题。在无法运行的情况下,很难确切地看到这么大的代码示例中发生了什么。
标签: c fork multiple-processes