由Signal想到的

  //作者: laruence<xinchen.hui at alibab-inc.com>
    //http://blog.csdn.net/laruence/
    //轉載請註明出處
   signal(int sig, void(*func)(int))是信號註冊函數。它可以定製對於特定的信號(sig)的處理函數。
昨天偶然看到他的申明式的時候,把我搞的有點糊塗
   #include <signal.h>
   void(*signal(int signo, void(*func)(int)))(int);

  仔細理解了半天,終於搞清楚了它的定義式,也解開了我長期以來的一個誤區:
1. void(*func)(int):
 定義了一個函數指針,他的類型是,指向一個返回是void,參數的int的函數類型的指針,就好像 int i, 定義了一個可以存儲int型的變量的i。
2. 由上,signal的定義可以如下解釋。
    signal(int signo, void(*func)(int));
 定義了,signal函數接受倆個參數一個是int signo,一個是一個回調的函數指針。
    void(* signal(....))(int);
 定義了,signal的返回類型是一個函數指針,指向一個返回空的,接受一個整形參數(信號值)的函數;
這麼解釋,就好多了,再看看簡化的定義式,就更明白了(Plauger 1992):
    typedef void sigfunc(int);
     sigfunc *signal(int, sigfunc *);
由此,我結合fork進行了一番試驗, 來驗證,子進程是否既成父進程的信號處理函數,代碼如下:

#ifndef _H_H_
#define _H_H_
#include 
<iostream>
#include 
<cstdio>
#include 
<cstdlib>
#include 
<csignal>
#include 
<cmath>
#include 
<ctime>
#include 
<sstream>
#include 
<string>
#include 
<vector>
#include 
<unistd.h>
#include 
<wait.h>
using namespace std;
void onSignal(int sig){
    cout 
<< "Sig No:" << sig <<endl;
    cout 
<< "I am killed" <<endl;
    cout 
<< "My Pid :" << getpid()<<endl;
    exit(
0);
}

void onExit(){
    cout 
<< "___________________________"<<endl;
    cout 
<< "I am Quit ,My Pid = "<< getpid() <<" Bye!"<<endl;
    cout 
<< "___________________________"<<endl;
}

void onChildExit(int sig){
    
int status;
    wait(
&status);
    
if(WIFEXITED(status)){
        cout 
<< "My Child process normally exit, exit status = "<< WEXITSTATUS(status) <<endl;
    }
else{
        cout 
<< "My Child process exit abnormally signal number = "<< WTERMSIG(status) <<endl;
    }

}

void onAlarm(int sig){
    pid_t pid;
//  pid = getpid();
    if((pid = fork()) < 0){
        abort();
    }
else if(pid == 0){
        cout 
<< "___________________________"<<endl;
        cout 
<< "I am child process"<<endl;
        cout 
<< "Pid : "<<getpid()<<endl;
        cout 
<< "Parent Pid : "<<getppid()<<endl;
        cout 
<< "___________________________"<<endl;
        sleep(
5);
    }
else{
        signal(SIGCHLD, onChildExit);
        cout 
<< "___________________________"<<endl;
        cout 
<< "I am parent process"<<endl;
        cout 
<< "My Child Pid : "<<pid<<endl;
        cout 
<< "Parent Pid : "<<getppid()<<endl;
        cout 
<< "My Pid : "<< getpid()<<endl;
        cout 
<< "___________________________"<<endl;
        sleep(
20);
    }

}

int main(int argc, char * argv[], char ** env){
    atexit(onExit);
    
if(signal(SIGINT, onSignal) != SIG_ERR){
        printf(
"Add SigInt Handle Successful! ");
    }

    signal(SIGALRM, onAlarm);
    alarm(
1);
    cout 
<< "Leave me alone for 10secs, I need have a nap" <<endl;
    pause();
    exit(
0);
}

 
最後執行, 結果爲:

Add SigInt Handle Successful!
Leave me alone 
for 10secs, I need have a nap
___________________________
I am child process
Pid : 
21313
Parent Pid : 
21312
___________________________
___________________________
I am parent process
My Child Pid : 
21313
Parent Pid : 
20899
My Pid : 
21312
___________________________
___________________________
I am Quit ,My Pid 
= 21313 Bye!
___________________________
My Child process nomarl exit, exit status 
= 0
___________________________
I am Quit ,My Pid 
= 21312 Bye!
___________________________

結論:
 子進程會既成父進程的信號處理函數; 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章