2014-03-05 71 views
5

我正在寫一個debugging utility,我想fork一個孩子,同時防止孩子終止觸發SIGCHLD到其父母。我仍然希望其他孩子在終止時通常會導致SIGCHLD有沒有辦法阻止一個特定的孩子觸發SIGCHLD?

我想這樣做,因爲我不想讓fork觸發現有的$SIG{CHLD}處理程序,但我仍然希望其他孩子觸發它。也就是說,我想孤立我的新孩子,我不希望它干擾現有孩子的管理。

我很警惕本地安裝自定義$SIG{CHLD}處理程序,因爲我不認爲我可以正確檢測何時應該調用原始處理程序。例如,如果我安裝了一個本地處理程序,那麼一旦我產卵了一個孩子,並且父母waitpid終止,我保證會收到一個SIGCHLD信號。但是,SIGCHLD不會指示其他孩子是否也已終止,因此我無法確定是否要調用原始處理程序。

我研究過程無法更改其父pid。我不確定是否要更改孩子的進程組ID或會話ID會很有用。

是否甚至有可能阻止特定的孩子觸發父母的SIGCHLD?當我收到孩子的SIGCHLD信號時,我不得不依靠現有的$SIG{CHLD}處理程序做正確的事情嗎?

儘管可能有更好的方法來實現該調試工具(讓我知道是否有),但我還是想知道POSIX是否對兒童提供瞭如此細緻的控制,並且正在尋找一種Perl解決方案給我困境。

回答

2

不能便攜防止SIGCHLD完全,但如果信號處理程序被寫入正確就可以防止waitpid函數從它成爲孤兒返回調試工具的PID。

use Signal::Mask; 
sub start_background_child { 
    local $Signal::Mask{CHLD} = 1; 
    my $first = fork; 
    croak "fork failed: $!" if not defined $first; 
    if ($first) { 
    waitpid $first, 0; 
    return; 
    } 

    my $second = fork; 
    croak "fork failed: $!" if not defined $second; 
    exit if $second; 

    your_stuff_here(); 
} 
+0

這種方法可能會或可能不會阻止初始的SIGCHLD(可移植性問題),但是如果不waitpid將永遠不會返回調試過程。 –

+0

儘可能完美!在我的MacBook(OS X 10.8.2)上,這可以按需要工作。另外,我喜歡你的'Signal :: Mask'和'Signal :: Pending'模塊;他們很容易探索我係統中的行爲。 :) – Mohith

1

我認爲你可以將特殊的兒童叉分開兩次 - 以切斷父母與子女的關係。創建過程時,您仍然會收到SIGCHLD - 我不知道這是否可以接受。

sub start_special_child { 
    return if fork;  # run rest of this routine in child process 
    fork && exit;  # run rest of this routine in grandchild process 
         # the exit here triggers SIGCHLD in the parent 
    ...     # now run your special process 
    exit;    # exit here does not trigger SIGCHLD 
} 

另一種方法是跟蹤你的子進程的進程ID的,並且使用waitpid找出哪個進程(ES)觸發SIGCHLD處理程序。

$SIG{CHLD} = \&sigchld_handler; 
$pid1 = start_child_process(); 
$pid2 = start_child_process(); 
$pid3 = start_child_process(); 
$pidS = start_special_child_process(); 

sub sigchld_handler { 
    $pid = waitpid -1, WNOHANG;  # use POSIX ':sys_wait_h' 
    return if $pid == $pidS; 
} 
+0

我想避免,最初的'SIGCHLD',所以第一種方法是不幸的是沒有適合我接受(因爲它仍然會引發現有'$ SIG {CHLD}'處理)。如果我控制了原來的'$ SIG {CHLD}'處理程序以及其他子程序,第二種方法將是理想的。但是,我正在尋找一種通用的解決方案,無論原始的「$ SIG {CHLD}」如何,並且不知道任何其他孩子。我也想避免收穫其他孩子(但我不介意是否收穫特殊孩子)。 – Mohith

+0

我通常不喜歡Perl的線程,但也許這裏的線程比fork更合適。 – mob

相關問題