2016-09-05 22 views
1

我在Mac OS上運行我的C程序。我的程序的一部分如下。此代碼在sigint信號上運行良好,但無法在sigkill信號上運行。在C,linux中,關於終止信號和睡眠()循環中

void sigkill(int sig){ 
    /*some code neglected*/ 
    exit(0); 
} 
void sigint(int sig){ 
    flag=1; 
} 

void alive(void) { 
    signal(SIGINT, sigint); 
    signal(SIGKILL, sigkill); 
    alarm(10); 
    while(1){ 
     //printf("%d\n",flag); 
     sleep(1); 
     if(flag==1){ 
      printf("no\n"); 
      flag=0; 
     } 
    } 
} 

我有四個問題:

  1. 起初我沒寫sleep(1),它可以進入功能SIGINT(),並更改標誌值,我可以從printf的看到。然而,沒有「不」的輸出,如我所料。

  2. 我添加睡眠功能後,效果很好。我猜while循環會每隔1秒檢查一次flag,如果flag = 1,輸出「no」。但是,當我按ctrl + c時,似乎每次都輸出「no」。爲什麼它不會等待一秒?

  3. 問題說:「你不應該使用sleep()'等待10秒,使用alarm(),加上一個循環。我想知道如何實現這個沒有睡眠()。

  4. kill命令不能調用sigkill函數,如何解決這個問題?

+3

你不能陷入'SIGKILL'期間。你不能爲'SIGKILL'設置陷阱。順便說一句,'SIGSTOP'。 –

+0

你知道如何在沒有睡眠的情況下實現它嗎? –

+0

混合'alarm()'和'sleep()'不是100%可靠的。你可以使用'alarm()'和'pause()'''pause()'只在中斷並且信號處理程序返回時才返回。你可以使用'select()'和'poll()'以及特定於平臺的變體來執行亞秒級的睡眠。你可以使用'nanosleep()'和'usleep()'來做睡眠的納秒和微秒分辨率(雖然精度通常不如分辨率)。如果你看起來很辛苦,那麼可能會有幾秒鐘的睡眠。 –

回答

3
  1. 一般情況下,信號只能被「捕獲」通過你的應用程序進行系統調用進入內核時。如果你做一個普​​通的while(1) { if (flag==1){...} },那永遠不會調用內核。理論上,當你在while(1)循環中做外部printf時,應該調用內核,因此信號可能被捕獲。
  2. sleep()被任何信號中斷。檢查手冊頁sleep(3)
  3. 檢查alarm(2)的手冊頁。
  4. 您不能更改SIGKILL的信號處理程序,也不能更改SIGSTOP的信號處理程序。這些信號效果被硬編碼到內核中。從sigaction(2)

    正負號指定信號,並且可以是除了SIGKILLSIGSTOP任何有效信號。

    不帶參數的kill命令不會生成SIGKILL信號;它會生成SIGTERM

+0

我不是很瞭解第三個答案。如何實施它沒有睡眠? –

+1

從'alarm(2)'的手冊頁:'alarm()安排一個SIGALRM信號以秒爲單位傳送給進程。 –