2016-03-13 44 views
0

我想用C语言开发3人游戏。该程序创建3个孩子和1个父母。家长打印并进入睡眠状态并向相关的孩子发送信号。小孩经过一些计算后会暂停,家长应该再次醒来。但是输出远没有接近它。我尝试在各个地方使用sleep(),但没有运气。是否有人可以帮助我走出C中的进程同步

void action(){} 
void child(char *); 
int main(int argc, char *argv[]) 
{ 
    pid_t pid1,pid2, pid3; 
    printf("This is a 3 player game\n"); 
    if((pid1=fork()==0)) child("TOTO"); 
    if((pid2=fork()==0)) child("TITI"); 
    if((pid3=fork()==0)) child("TUTU"); 

    sleep(1); 
    signal(SIGUSR1, action); 
    while(1) 
    { 
     printf("\nRefree: TOTO Plays\n\n"); 
     kill(pid1,SIGUSR1); 
     pause(); 
     printf("\nRefree: TITI Plays\n\n"); 
     kill(pid2,SIGUSR1); 
     pause(); 
     printf("\nRefree: TUTU Plays\n\n"); 
     kill(pid3, SIGUSR1); 
     pause(); 
    } 
} 
void child(char *s) 
{ 
    int points=0,dice; 
    while(1) 
    { 
     signal(SIGUSR1, action); 
     pause(); 
     printf("\n%s: Playing my dice\n",s); 
     dice = (rand() % 10)+1; 
     printf("%s: got %d points\n",s, dice); 
     points+=dice; 
     printf("%s: Total so far %d\n\n", s, points); 
     sleep(2); 
     if(points >= 50) 
     { 
      printf("%s: game over I won\n", s); 
      kill(0, SIGTERM); 
     } 
     kill(getppid(), SIGUSR1); 
    } 
} 

输出我得到的是

This is a 3 player game 

Refree: TOTO Plays 




TITI: Playing my dice 
TUTU: Playing my dice 
TOTO: Playing my dice 
TUTU: got 4 points 
TOTO: got 4 points 
TOTO: Total so far 4 

TITI: got 4 points 
TUTU: Total so far 4 

TITI: Total so far 4 

User defined signal 1 

回答

2

你的括号是错误的。您写道:

if((pid1=fork()==0)) child("TOTO"); 

它应该是:

if((pid1=fork())==0) child("TOTO"); 

你的情况会发生什么事是你指派0至pid1pid2,并在父进程pid3和1的子进程,因为在赋值运算符=之前对fork()==0进行评估。

我会建议不要在表达式中使用带有副作用的操作(虽然我知道这是常见的做法)。毕竟,如果你花了一个多行,你可能会完全避免这个问题:

pid1 = fork(); 
if (pid1 == 0) child("TOTO"); 

操作与副作用,如=+=*=++--等作为单独使用时,是最安全的声明。在其他表达式中,它们的含义可能不清楚甚至没有定义。在下面的语句:

x = x++ + 1; 

++可以=之前应用的增量评估或之后。如果最初为x = 0,则x之后可能为1或2。

+1

与'x ++'很好的搭配..这实际上意味着代码会导致未定义的行为。 –

0
pid1=fork()==0 

这是讨厌的,但你实际上在这里做的是:

pid1 = (fork() == 0) 

操作==higher precedence比运营商=

如果你想让你的游戏是乐趣但要注意,你或许应该种子的随机数,否则就......有点无聊;)

您可以srand(time(NULL));

种子的随机数

此外,作为一般性的建议:检查系统调用(如fork)以及库函数(malloc)可能失败的错误。此外,使用signalnot recommended

+0

谢谢。我看到这是一个愚蠢的错误。我接受了你的建议,不使用信号,现在我将使用pipe()和dup()系统调用来尝试同样的事情,让父母等待,直到孩子正在玩。这将使我的程序更有效率。 –