- 本文地址: https://www.laruence.com/2008/04/04/114.html
- 转载请注明出处
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);
}
#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!
___________________________
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!
___________________________
结论:
子进程会继承父进程的信号处理函数;
沙发
沙发
沙发