2012-02-15 97 views
2

這個程序的目標是分叉並讓子進程休眠,同時父進程無限等待中斷。當我點擊^ C時,它會調用void parent函數。然而,這部分工作,從kill (pid, SIGALRM)消息不起作用。我檢查了並且pid是孩子正確的進程ID。C++進程fork和sigalarm

我搜索了一段時間,但我還沒有找到我做錯了什麼。我之前使用的kill (pid, SIGALRM)從子進程到父,但我想不通這是爲什麼不工作..

#include <signal.h> 
#include <unistd.h> 
#include <iostream> 
#include <sys/types.h> 
#include <sys/wait.h> 

using namespace std; 

int pid; 

void parent (int sig) 
{ 
     kill (pid, SIGALRM); 
     cout << "I'm a parent " << getpid() << " My child is " << pid << endl; 
} 

void child (int sig) 
{ 
     cout << "I am " << getpid() << "my parent is " << getppid()<< endl; 
     cout << "Use ctrl+backslash to actually end the program" << endl; 
} 
int main() 
{ 
     pid = fork(); 
     if(pid == 0) 
     { //Child process 
       cout << "Child pid = " << getpid() << " Waiting for interrupt." << endl; 
       (void) signal (SIGALRM, child); 
       pause(); 
     } 
     else if(pid > 0) 
     { //Parent 
       sleep(2); 
       cout << "child pid = " << pid << endl; 
       struct sigaction act; 
       act.sa_handler = parent; 
       sigemptyset (&act.sa_mask); 
       sigaction (SIGINT, &act, 0); 
       while(1) 
       { 
         sleep (1); 
       } 
     } 
     return 0; 
} 
+1

什麼是輸出,你在做什麼操作系統?此外,在這裏迂腐,那些信號處理程序應該用C鏈接來定義。 (即把它們放在extern「C」塊內) – Arafangion 2012-02-15 07:09:57

+0

另外,你如何知道iostreams在信號處理程序中是否安全?我想知道如果這是http://stackoverflow.com/questions/7623401/override-ctrl-c重複(但即使是這樣,我認爲這個問題值得保持原樣) – Arafangion 2012-02-15 07:12:14

+0

我使用Fedora 15 。 我得到的輸出是: '兒童的pid = 23779等待interrupt.' '孩子的pid = 23779' '^ CI'm父23778我的孩子23779' '^ CI'm父23778我的孩子是23779'''' \退出(核心傾銷)' 並感謝您的外部C塊,我從來沒有使用過之前 – OrangeGrover 2012-02-15 07:19:10

回答

0

好了,我想通了這個問題。
當我按^ C時,它會捕獲主進程中的中斷,但會終止子進程。當我從程序內部運行system("ps")時,它顯示孩子a.out進程失效。 爲了解決這個問題,我添加以下孩子的過程:

struct sigaction act; 
act.sa_handler = CHILD_PRESERVER; 
sigemptyset (&act.sa_mask); 
sigaction (SIGINT, &act, 0); 

CHILD PRESERVER是,什麼也沒做,除了保持它活着的虛擬功能。

它沒有看到這個解決方案是非常優雅的,所以如果任何人有一個更正確的方式做到這一點,請張貼它。

0

您可以只使用signal(SIGINT, SIG_IGN);

絆倒您最初(並且經常絆倒了處理CTRL-C和信號新程序員)的東西做同樣的事情,你的sigaction的解決方案是,CTRL-C發送一個信號傳送給整個過程組,而不是一個過程 - 組中的每個過程都會得到信號。信號發送到的進程組是終端的前臺進程組。

因此,這給你很多處理/控制ctrl-C中斷的方法。您可以讓每個進程安裝自己的SIGINT處理程序(如您所做的那樣)。或者你可以仔細管理你的過程組,把孩子放到他們自己的過程組(通常不是前臺過程組),所以他們不會首先得到信號。

您可以使用setpgrp(2)/ setpgid(2)系統調用來管理進程組。