我正在用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? –