msgbartop
PHP应用,PHP源码分析,Zend引擎分析,Web相关技术研究,Web技术分享 – 左手代码 右手诗
msgbarbottom

04 Apr 08 由signal想到的

    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!
___________________________

结论:

 子进程会既成父进程的信号处理函数;

Related Posts:

  • No Related Post

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word