Assignment 5¶
Signal¶
In the following code, the child sends 10 signals to its parent and then the parent counts the total number.
-
What's the output of the parent? Explain your answer.
-
if fork() is replaced with vfork(), is your answer still the same? Why?
int count = 0;
void handler(int sig)
{
count++;
return;
}
int main()
{
int i, status;
signal(SIGUSR1, handler);
if ( fork() == 0 ) {
for ( i = 0; i < 10; i++ )
kill(getppid(), SIGUSR1);
exit(0);
}
wait(&status);
printf("Got %d signals\n", count);
}
My Answer¶
假設:在執行signal handler之後該handler不會被reset成default action。
-
count可能是1到10的任何一個數字。 因為若我們使用 fork(),便有可能在child和parent之間context switch。由於當parent不在CPU執行時,signal會被generate但不會被deliver,系統會將process table中的一個flag on起來表示這個signal是在pending的狀態。所以若是在這時重複generate該signal,在deliver時也還是只會有一次(因為flag只有on/off兩種狀態)。因此,child送給parent的10次SIG_USR1可能會有數次是這種情況,在極端情況下,child可能送完10次後才context switch到parent,如此parent就只會被deliver一次SIG_USR1,最終count為1。或者child每送一次SIG_USR1,就context switch到parent去執行signal handler,再回到child送下一次signal,這樣就會有10次deliver,則count為10。
附註:若該系統在每次signal handler執行完後便會將該signal的action重設成default action,則handler()最多執行一次,且因為SIG_USR1的default action是terminate,所以若SIG_USR1發生第二次deliver,parent process便會被強制結束,而不會print "Got ? signals"。
-
不,和(a)不同,count永遠是1。 因vfork()會suspend parent process直到child process return。所以child會完整送完10次SIG_USR1才會回到parent,由於系統處理pending signal的機制是把process table中的flag on或off,所以就算送了10次,對系統來說最後都是一個on的狀態而已,在回到parent時只會deliver一次就結束了。所以 handle()只會執行一次,故count最終必為1。