Press "Enter" to skip to content

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

___________________________

结论:

 

子进程会继承父进程的信号处理函数;

 

3 Comments

  1. 燕玉苗
    燕玉苗 2015-12-03

    沙发

  2. 燕玉苗
    燕玉苗 2015-12-03

    沙发

  3. 燕玉苗
    燕玉苗 2015-12-03

    沙发

Leave a Reply

Your email address will not be published. Required fields are marked *