簡體   English   中英

為什么我的信號處理程序執行兩次?

[英]Why my signal handler executes twice?

我正在學習Linux中的進程間通信,使用kill()向正在休眠的子進程發送信號,這是我的程序:

 8 void func(void);
 9 int main(void){
 10         int i, j;
 11         pid_t status, retpid;
 12         signal(17,func);
 13         if( i = fork() ){
 14                 printf("Parent:signal 17 will be sent to child!\n");
 15                 kill(i, 17);
 16                 wait(0);
 17                 printf("child process terminated\n");
 18                 }
 19         else{   
 20                 sleep(10);
 21                 printf("Child: A signal from my parent is received!\n");
 22                 exit(0);
 23         }
 24 }
 25 void func(void) 
 26 {
 27         printf("the signal has been sent!\n");
 28 }

用gcc編譯,程序產生異常結果,其中func()執行兩次:

./test4.out
Parent:signal 17 will be sent to child!
the signal has been sent!
Child: A signal from my parent is received!
the signal has been sent!
child process terminated

我分析了結果,然后刪除了以下兩行:

 16                 wait(0);
 17                 printf("child process terminated\n");

結果變為正常,僅調用一次func()。 罪魁禍首似乎是wait()函數,但是為什么會調用信號處理程序呢?

您正在向子進程發送信號17,因此將按預期調用其處理程序。

信號17是SIGCHLD 當子進程死亡時, SIGCHLD被發送到父進程。 子項退出時,將調用父項的處理程序。 這個信號不是來自父母的。 它來自操作系統,用於通知父母孩子的死亡。

更正(大多數)已發布代碼中的錯誤之后。

結果是以下代碼:

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

void func( int );

int main(void)
{
    pid_t i;
    //pid_t status;
    //pid_t retpid;
    signal(17,func);


    if( (i = fork()) )
    {
        printf( "the fork'd child pid:%d\n", i );
        printf("Parent:signal 17 will be sent to child!\n");
        kill(i, 17);
        wait(NULL);
        printf("child process terminated\n");
    }

    else
    {   
        sleep(10);
        printf("Child: pid:%d\n", getpid());
        exit(0);
    }
}

void func( int theSignal) 
{
    if( 17 == theSignal )
    {
        fprintf( stdout, "the 17 signal has been processed by %d!\n", getpid());
    }

    else
    {
        fprintf( stdout, "the %d signal is processed\n", theSignal );
    }
}

輸出為:

the fork'd child pid:4845
Parent:signal 17 will be sent to child!
the 17 signal has been processed by 4845!
Child: pid:4845
the 17 signal has been processed by 4844!
child process terminated

這清楚地表明父母和孩子都在處理信號

編輯:

但是,當使用唯一的SIGUSR2值時,如以下代碼所示:

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

void func( int );

#define MY_SIGNAL (31)

int main(void)
{
    pid_t i;
    //pid_t status;
    //pid_t retpid;
    signal(17,func);
    signal(31,func);

    if( (i = fork()) )
    {
        printf( "the fork'd child pid:%d\n", i );
        printf("Parent:signal %d will be sent to child!\n", MY_SIGNAL);
        kill(i, MY_SIGNAL);
        wait(NULL);
        printf("child process terminated\n");
    }

    else
    {   
        sleep(10);
        printf("Child: pid:%d\n", getpid());
        exit(0);
    }
}

void func( int theSignal) 
{
    if( MY_SIGNAL == theSignal )
    {
        printf("the %d signal has been processed by %d!\n", MY_SIGNAL, getpid());
    }

    else
    {
        printf( "the %d signal is processed\n", theSignal );
    }
}

那么輸出是:

the fork'd child pid:5099
Parent:signal 31 will be sent to child!
the 31 signal has been processed by 5099!
Child: pid:5099
the 17 signal is processed
child process terminated

清楚地顯示了子處理信號31(SIGUSR2)和父處理信號17(SIGCHLD)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM