我正在用3个进程编程系统,Judge
,Player 1
和player 2
。linux c程序中的信号
我用信号kill(playerPid,SIGUSR1)
为judge
醒来就轮到他一个player
, 和信号kill(judge,SIGHUP)
唤醒法官后,又是完整的。
之后每个kill signal
我使用pause()
所以过程将不会继续。 问题有时在kill signal
之后,例如从player
到judge
,judge
在玩家正在做他的pause()
之前醒来。 和下一次judge
会唤醒这个player
他会pause
和我的程序将堆栈,因为所有3 processes
处于pause
状态,没有人唤醒它们。
so so question is: kill命令后会发生什么?
。当前过程一直持续到暂停(),然后进入他发出信号的过程。 例如:
kill(judge, SIGHUP);
//stops here and goes to the judge.
pause();
这就是有时会发生在我的代码和我卡住与pause()
的所有进程。
。当前进程停止并进入他刚刚发送的进程。 例如:
kill(judge, SIGHUP);
pause();
//stops here and going to the judge.
**这是大部分的时间发生在我的代码。
在我的代码的行为的变化,有时它像1号,有时像数2
我到底做错了什么?
在接收到信号的处理函数完成运行之前,是否可以唤醒进程?
或者在进入暂停行之前,进程是否可能在kill信号后暂停?如果是的话,为什么以及如何处理?
这里是我的代码:
///////////////////////signal handlers
void sigHandler(int signo)
{
printf("Received signal %d\n", signo);
if(signo == SIGHUP)//fatehr gets it from son
{
signal(SIGHUP ,sigHandler);
printf("son woke up father\n");
}
else if (signo == SIGUSR1)//son gets it from father
{
signal(SIGUSR1, sigHandler);
printf("Judge waking player B\n");
}
else if (signo == SIGUSR2)//father gets it from son
{
signal(SIGUSR2, sigHandler);
printf("Judge waking player A\n");
}
else if (signo == SIGTERM)//son get it when father kill them
{
signal(SIGTERM, sigHandler);
printf("%d im dead\n", getpid());
kill(getppid(), SIGUSR2);
exit(1);
}
else if (signo == SIGINT)//father get it to play round with ^C
{
signal(SIGINT, sigHandler);
printf("play round!!!!!!!!!!!!\n");
}
}
void sigHandler2(int signo)
{
if (signo == SIGINT)//son get it to play round with ^C
{
signal(SIGINT, sigHandler2);
}
}
void wakePlayer(int player,int turn, int* boardPtr)
{
boardPtr[27] = 0;
while (boardPtr[27] != 1)//while player didnt finish his turn
{
if (turn==1)
kill(player, SIGUSR1);
else
kill(player, SIGUSR2);
pause();
}
}
///////////////////////End of signal handlers
int main(){
int j = 1;;
int player1;
int player2;
int judge;
time_t t;
key_t key;
int shmid;
int *boardPtr;
judge = getpid();
srand(time(NULL) *(5));
shmid = createShm(&boardPtr);//creating shm
boardPtr[1] = 2;
player1 = fork();//create player 1
if (player1 == -1)
{
printf("error in fork");
exit(1);
}
if (player1>0)//not player 1
{
player2 = fork();//create player 2
if (player2 == -1)
{
printf("error in fork");
exit(1);
}
if (player2>0)//This is The Judge!********************************************************************************
{
signal(SIGHUP, sigHandler);//signal from player after he did his turn
signal(SIGINT, sigHandler);//catch the ^c to make the next turn
printf("father started\n");
while(boardPtr[1]!=0)//Players didnt set up their handlers
{
sleep(1);
}
printf("father initiating\n");
initiation(boardPtr, player1, player2);//create the board and choose a player to start
printBoard(boardPtr, 0);//print the current board.
while (checkWin(boardPtr) == 0)//while no one won.
{
if (boardPtr[26] == 1)//if it is player "b" turn.
wakePlayer(player1,1, boardPtr);
else //if it is player "a" turn.
wakePlayer(player2,2, boardPtr);
//pause();
printBoard(boardPtr, j);//print the current board.
boardPtr[26] = (boardPtr[26] * 2) % 3;//change turns
j++;
}
printf("game finished!\n");
killItWithFire(player1, player2, shmid, &boardPtr);//cleaning up after match.
printf("Judge is suiciding, goodbye!\n");
exit(1);
}
else if (player2 == 0)//this is player 2!******************************************************************************
{
signal(SIGUSR2, sigHandler);//signal from judge to make a turn
signal(SIGTERM, sigHandler);//signal from judge to terminate
signal(SIGINT, sigHandler2);//get the ^c and pause.
printf("%d player A started\n", getpid());
boardPtr[1]--;//mark player A handlers are set.
pause();
while (1)
{
int r = roll(1);
printf("%d player A threw a %d\n", getpid(), r);
if (boardPtr[22] == 0)//checking if it is an initation round
{
boardPtr[21] = r;
}
else
{
turn(2, r, boardPtr);//makes a turn
}
boardPtr[27] = 1;//mark that i finished my turn.
kill(judge, SIGHUP);//signal to judge after turn.
pause();
}
}
}
else//this is player 1!**********************************************************************************************
{
signal(SIGUSR1, sigHandler);//signal from judge to make a turn
signal(SIGTERM, sigHandler);//signal from judge to terminate
signal(SIGINT, sigHandler2);//signal to pause when player gets a ctrl C
printf("%d player B started\n", getpid());
boardPtr[1]--;//mark player A handlers are set.
pause();
while (1)
{
int r = roll(2);
printf("%d player B threw a %d\n", getpid(), r);
if (boardPtr[22] == 0)//flag to check if it is an initiation round.
{
boardPtr[20] = r;
}
else
{
turn(1, r, boardPtr);//player b makes a turn
}
boardPtr[27] = 1;//marks that player B finished his turn.
kill(judge, SIGHUP);//signal to judge after turn.
pause();
}
}
return 0;
}
可以请你解释一下什么是所有这些功能,并且击杀后,预计什么命令?继续直到暂停,或者直接进入发信过程。 –
感谢您的意见。所以基本上你对你的解决方案所说的是,在我的kill命令和暂停之间,有一个信号会让我的进程在他暂停之前睡眠? –
什么是signaltowait?我应该传递什么信号给那个arg? –