[英]C Can't signal a child process to continue after `sigsuspend`
我正在嘗試創建一個程序,其中一個進程分叉,創建一個子進程,並且父進程必須始終在子進程完成打印到屏幕之前完成打印到屏幕,無論如何。 我也希望使用信號而不是流水線來實現這一點。
這是一個與這里提出的問題類似的問題: 需要 sigsuspend 的解釋
我明白kill(pid,signal);
是向該 pid 發送信號並告訴它完成執行並終止。
問題是,當它執行時,子進程在掛起后不會打印。 代碼如下:
int main(void){
pid_t pid;
int i;
pid = fork();
if(pid==0){
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask,SIGUSR1);
printf("This is the child Process id = %d \n",getpid());
sigsuspend(&mask);
printf("The child is now complete \n");
}
else{
printf("This is the parentProcess id = %d \n",getpid());
printf("The parentProcess is complete\n");
sleep(1);
int j = kill(pid,SIGUSR1);
if (j!=0)
{
perror(NULL);
}
exit(0);
}
}
我設法通過使用全局變量int x = 0;
完成了我的任務(在孩子之前打印父母) int x = 0;
和信號處理方法void handle1(int s){x = 1;}
在 main 之前。 在主要我添加了signal(SIGUSR1,handle1);
在孩子中,我刪除了所有 sigset 和 sigsuspend 行,而是在printf
語句之前寫了while(x==0){/*do_nothing*/}
1 行。 因此,當父進程執行kill(pid,SIGUSR1)
,子進程繼承的信號處理程序也會被執行並設置 x=1。 所以孩子現在離開while循環並可以打印它的語句。
但是我相信知道如何使用sigmask_t
和sigsuspend()
完成這項任務會很有幫助,但我無法讓它以這種方式工作。
你有幾個問題。
您的父進程應該等待子進程完成。 這允許診斷(例如正確等待孩子打印),但在其他方面是一個簿記任務,即使等待進程將退出,也是一個好習慣:
printf("This is the parentProcess id = %d \n",getpid());
printf("The parentProcess is complete\n");
sleep(1);
int j = kill(pid,SIGUSR1);
if (j!=0)
{
perror(NULL);
exit(0);
}
waitpid(pid, NULL, 0);
exit(0);
現在,您已將掩碼中的SIGUSR1
設置為sigsuspend()
,這會導致信號被忽略。 一旦父級等待,這現在更加明顯,因為父級永遠不會退出。 因此,刪除設置SIGUSR1
的代碼行。
最后, SIGUSR1
的默認處理程序只會導致進程退出,因此printf
將沒有機會打印。 如果你想打印它,你應該為SIGUSR1
添加一個信號處理程序。 它不必做任何事情。
void h (int s) {}
...
sigset_t mask;
sigemptyset(&mask);
//sigaddset(&mask,SIGUSR1);
printf("This is the child Process id = %d \n",getpid());
struct sigaction sa = { .sa_handler = h };
sigaction(SIGUSR1, &sa, NULL);
sigsuspend(&mask);
printf("The child is now complete \n");
您的代碼中有 3 個問題:
SIGUSR1
是你想傳遞給孩子的信號。 你不能使用sigaddset(&mask,SIGUSR1);
,它與您的意圖完全相反。
根據下面的 POSIX 標准sigsuspend()
,您應該為SIGUSR1
安裝一個信號處理程序,以使sigsuspend()
繼續以下代碼,因為SIGUSR1
的默認行為是終止。
sigsuspend() 函數應該用 sigmask 指向的一組信號替換調用線程的當前信號掩碼,然后掛起線程直到傳遞一個信號,該信號的動作是執行信號捕獲函數或終止進程.
下面的代碼將起作用:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void handler(int sig) {}
int main(void){
pid_t pid;
int i;
pid = fork();
signal(SIGUSR1, handler);
if(pid==0){
sigset_t mask;
sigemptyset(&mask);
//sigaddset(&mask,SIGUSR1);
printf("This is the child Process id = %d \n",getpid());
sigsuspend(&mask);
printf("The child is now complete \n");
}
else{
printf("This is the parentProcess id = %d \n",getpid());
printf("The parentProcess is complete\n");
sleep(1);
int j = kill(pid,SIGUSR1);
if (j!=0)
{
perror(NULL);
}
wait(NULL);
exit(0);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.