2013-01-19 151 views
4

我是新手,請溫柔我複製從一本書的代碼:此代碼是否有邏輯錯誤? !

#include <sys/types.h> 
#include <signal.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

static int alarm_fired = 0; 

void ding(int sig) 
{ 
    alarm_fired = 1; 
} 

int main(int argc, char* argv[]) 
{ 
    pid_t pid; 

    printf("alarm application starting\n"); 

    pid = fork(); 

    switch(pid) 
    { 
     case -1: 
      perror("fork failed"); 
      exit(EXIT_FAILURE); 
     case 0: 
      sleep(5); 
      kill(getpid(), SIGALRM); 
      exit(EXIT_SUCCESS); 
    } 
    printf("waiting for alarm to go off\n"); 
    (void) signal(SIGALRM, ding); 

    pause(); 
    if (alarm_fired) 
     printf("Ding!\n"); 

    printf("done\n"); 
    exit(EXIT_SUCCESS); 
} 

正如作者寫:

ding,模擬報警clock.the子進程等待在將SIGALRM信號發送給其父母之前,向其發送 秒。


我試圖上面的代碼,但它具有打印alarm application starting

waiting for alarm to go off。所以我懷疑該碼具有邏輯和error.The線沒有響應kill(getpid(), SIGALRM);可以wrong.Am我右?

+2

「它不起作用」 - 實際發生了什麼? – Joe

+0

@Joe我編輯了這個問題,我很抱歉。 – prehistoricpenguin

+0

goto [code_review](http://codereview.stackexchange.com); – 2013-01-19 02:54:35

回答

4

你說得對,行

kill(getpid(), SIGALRM); 

是錯的,如果孩子到它的父發送信號。事實上,它試圖向自己發送一個信號,因爲他正在通過getpid()(獲取進程ID)傳遞自己的pid。

您應該使用getppid()(獲取父進程ID),這樣你就可以將消息發送給父進程,就像這樣:

kill(getppid(), SIGALRM); 
+1

該代碼還有一個競爭條件:如果在fork之後父級以某種方式被阻止執行很長時間,則信號處理程序在信號到達之前不會被設置。爲了實現這一點,您需要在調用fork之前設置信號處理程序,或者如果您不希望在子級中更改信號處理,請在分叉前阻止信號,並在設置處理程序後僅在父級中解除阻止信號(立即解除對孩子的阻擋是好事)。 –

+0

@ R ..是的,這本書提到它。 – prehistoricpenguin

1

這條線:

kill(getpid(), SIGALRM); 

由子執行併發送警報信號給自己。

這條線:

signal(SIGALRM, ding); 

爲母公司設立的報警信號

信號處理器和該行正在等待信號:

pause(); 

您需要的孩子將信號發送給父母而不是自己,然後所有的多米諾骨牌都會掉下來。