2010-04-23 109 views
1

所以基本上我希望「cmd_limit」在秒內獲取一個數字,這是我們等待子進程(安全地假設只有一個)完成的最長時間。如果子進程在睡眠期間完成,我希望cmd_limit返回通過,而不運行cmd_limit代碼的其餘部分。任何人都可以幫助我做到這一點,這是我迄今爲止..C信號和進程

int cmd_limit(int limit, int pid) { 

    signal(SIGCHLD, child_died); 
    sleep(limit); 
    kill(pid, SIGKILL); 
    printf("killin'\n"); 
    return PASS; 
} 

void child_died(int sig) { 

    int stat_loc; /* child return information */ 
    int status; /* child return status */ 

    waitpid(-1, &stat_loc, WNOHANG); 

    if(WIFEXITED(stat_loc)) { // program exited normally 
     status = WEXITSTATUS(stat_loc); /* get child exit status */ 
    } 

    printf("child died: %s\n", signal); 

} 
+0

你看過'alarm()'嗎? – 2010-04-23 12:33:30

+0

我知道警報,但我不知道如何確保在使用警報睡眠期間可以從cmd_limit返回? – Gary 2010-04-23 12:46:01

+0

'sleep'被不被忽略的信號中斷(詳細閱讀'sleep'手冊頁),如果這就是你想知道的。它還會返回中斷時的剩餘時間,如果不中斷則返回0。但是,您不應該在某些系統上混合調用「睡眠」和ALRM信號。 – outis 2010-04-23 14:17:06

回答

2

如果發送信號,kill返回0,如果沒有發送信號,則返回-1。如果進程已經退出,則不能發送信號,所以kill的返回值可以用來告訴您進程是否被殺死或已經死亡。

此外,您可以使用其中一個等待系統調用來查看子進程的狀態更改(包括退出)。

您還應該研究父進程中SIGCHLD的信號處理方式,當孩子改變狀態(包括退出)時父代會接收信號,並且還會將父母踢出睡眠狀態(儘管在某些系統上睡眠函數可能會重新啓動睡眠)

如果孩子在您的時間限制內退出,使用wait和/或SIGCHLD可以使父母更快完成工作。

您應該注意,您可能應該呼叫等待子進程退出,以便您不創建殭屍(進程稱爲退出但必須保留以防止父進程查看退出狀態) 。

你想要研究的另一件事是errno值EINTR,系統調用可以設置它們是否被信號中斷。

從您的命令行中鍵入:

man errno 
man 2 wait 
man 2 sigaction 

約我談到過的事情的詳細信息。

+0

好信息,我會考慮 - 謝謝:) – Gary 2010-04-23 21:02:57

1

你的意思是這樣的嗎?

bool childDied; 

int cmd_limit(int limit, int pid) { 
    childDied = FALSE; 
    signal(SIGCHLD, child_died); 
    sleep(limit); 
    if (!childDied) 
    { 
     kill(pid, SIGKILL); 
     printf("killin'\n"); 
    } 
    return PASS; 
} 

void child_died(int sig) { 
    int stat_loc; /* child return information */ 
    int status; /* child return status */ 

    childDied = TRUE; 

    waitpid(-1, &stat_loc, WNOHANG); 

    if(WIFEXITED(stat_loc)) { // program exited normally 
     status = WEXITSTATUS(stat_loc); /* get child exit status */ 
    } 

    printf("child died: %s\n", signal); 

} 
+0

這是正確的,除非事實上,如果限制= 200和孩子在10秒內死亡,我們仍然必須等待200秒,在程序中做任何其他事情。 – Gary 2010-04-23 21:01:57

+0

@加里:如果這是一個問題,你可以使用計數到所需總數的循環計數器替換一個較大的睡眠呼叫和幾個較短的呼叫。每次循環檢查子進程是否已退出。 – torak 2010-04-23 21:34:12