设置信号信号处理函数void (*signal (int signo ,void (*fun)(int )))(int)
来源:互联网 发布:power point for mac 编辑:程序博客网 时间:2024/05/16 05:51
设置信号信号处理函数void (*signal (int signo ,void (*fun)(int )))(int)
一个进程收到信号时需要跳转到信号处理函数的代码处执行。系统为每个信号提供给了多种默认的处理方式。
linux允许用户提供自己的信号处理函数,使用signal函数将处理函数加载,并且通知系统.
函数原型:
#include<signal.h>
void (*signal (int signo ,void (*fun)(int )))(int)
函数原型各参数详细解释
(一)signal函数的第一个参数是需要加载处理的信号编号,例如
SIGKILL等,该编号是一个宏,其本质是一个整数,定义在signal.h文件中
(二)第二个参数是一个函数指针,这个函数捕捉到第一个函数指定的信号,并对其进行处理,该参数可以是以下三个值中的一个
1)SIG_IGN:表示忽略该信号,即捕捉到信号后不做任何处理,该宏定义在signal.h文件中
#define SIG_IGN ((void *)(*)())1
2)SIG_DFL表示使用默认的信号处理方式,这样可以对此信号恢复系统的默认处理方式,该宏定义在signal.h文件中
#define SIG_DFL ((void *)(*)())0
3)其他已定义的函数指针:表示使用用户自己的处理函数处理此信号,
该信号成为信号处理函数,信号处理函数的原型为:void handler(int);
signal函数的返回值也是一个函数指针,这个函数指向上一次的信号处理程序,因此这个函数和signal的第二个参数所表示的的参数原型一致
,如果出错,signal函数返回SIG_ERR ,该宏定义在signal.h文件中
的多个信号可以共用一个处理程序,处理程序内部的流程只需要根据参数来判断即可了。
信号处理函数如下:
void handler( int signo )
{
switch(signo)
{
case SIGUSR1:
......
case SIGUSR2:
......
......
case SIGUSRn:
......
}
}
下面的程序展示了父子进程使用SIGUSR1和SIGUSR2进行通信
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
void handler( int signo )
{
switch(signo)
{
case SIGUSR1:
printf("parent :catch SIGUSR1\n");break;
case SIGUSR2:
printf("child :catch SIGUSR2\n");break;
default :
printf("should not be here\n");break;
}
return ;
}
int main( void )
{
pid_t ppid, cpid ;
/*为两个进程设置信号处理函数*/
if( signal(SIGUSR1, handler)== SIG_ERR)//设置出错
{
perror("can`t set handle for SIGUSR1");
exit(1);
}
if( signal(SIGUSR2, handler)== SIG_ERR)//设置出错
{
perror("can`t set handle for SIGUSR2");
exit(1);
}
ppid = getpid();//得到父进程id
if((cpid = fork() )< 0 )//创建子进程
{
perror("fail to fork");
exit(1);
}
else if(cpid == 0)
{//子进程向父进程发送SIGUSR1信号
if(kill(ppid,SIGUSR1)== -1)
{
perror("fail to send signal");
exit(1);
}
while(1);//死循环,等待父进程的信号
}
else
{
sleep(1);//休眠,保证子进程先运行,并且发送SIGUSR1信号
//向子进程发送SIGUSR2信号
if(kill(cpid,SIGUSR2) == -1)
{
perror("fail to send signal");
exit(1);
}
printf("kill child\n");//输出提示信息
if(kill(cpid,SIGKILL)== -1)//发送SIGKILL信号杀死子进程
{
perror("fail to send signal");
exit(1);
}
if(wait(NULL) == -1 )//回收子进程状态,避免僵尸进程
{
perror("fail to wait");
exit(1);
}
}
return 0;
}
一个进程收到信号时需要跳转到信号处理函数的代码处执行。系统为每个信号提供给了多种默认的处理方式。
linux允许用户提供自己的信号处理函数,使用signal函数将处理函数加载,并且通知系统.
函数原型:
#include<signal.h>
void (*signal (int signo ,void (*fun)(int )))(int)
函数原型各参数详细解释
(一)signal函数的第一个参数是需要加载处理的信号编号,例如
SIGKILL等,该编号是一个宏,其本质是一个整数,定义在signal.h文件中
(二)第二个参数是一个函数指针,这个函数捕捉到第一个函数指定的信号,并对其进行处理,该参数可以是以下三个值中的一个
1)SIG_IGN:表示忽略该信号,即捕捉到信号后不做任何处理,该宏定义在signal.h文件中
#define SIG_IGN ((void *)(*)())1
2)SIG_DFL表示使用默认的信号处理方式,这样可以对此信号恢复系统的默认处理方式,该宏定义在signal.h文件中
#define SIG_DFL ((void *)(*)())0
3)其他已定义的函数指针:表示使用用户自己的处理函数处理此信号,
该信号成为信号处理函数,信号处理函数的原型为:void handler(int);
signal函数的返回值也是一个函数指针,这个函数指向上一次的信号处理程序,因此这个函数和signal的第二个参数所表示的的参数原型一致
,如果出错,signal函数返回SIG_ERR ,该宏定义在signal.h文件中
#define SIG_ERR (void (*)())-1
信号是异步的通信方式,其到来由系统通知应用程序,所以信号处理函数是由系统调用的,其参数表示当前所捕捉到的信号的编号,也就是说该参数其实和signal的第一个参数signal是等效的。这样的好处是多余的多个信号可以共用一个处理程序,处理程序内部的流程只需要根据参数来判断即可了。
信号处理函数如下:
void handler( int signo )
{
switch(signo)
{
case SIGUSR1:
......
case SIGUSR2:
......
......
case SIGUSRn:
......
}
}
下面的程序展示了父子进程使用SIGUSR1和SIGUSR2进行通信
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
void handler( int signo )
{
switch(signo)
{
case SIGUSR1:
printf("parent :catch SIGUSR1\n");break;
case SIGUSR2:
printf("child :catch SIGUSR2\n");break;
default :
printf("should not be here\n");break;
}
return ;
}
int main( void )
{
pid_t ppid, cpid ;
/*为两个进程设置信号处理函数*/
if( signal(SIGUSR1, handler)== SIG_ERR)//设置出错
{
perror("can`t set handle for SIGUSR1");
exit(1);
}
if( signal(SIGUSR2, handler)== SIG_ERR)//设置出错
{
perror("can`t set handle for SIGUSR2");
exit(1);
}
ppid = getpid();//得到父进程id
if((cpid = fork() )< 0 )//创建子进程
{
perror("fail to fork");
exit(1);
}
else if(cpid == 0)
{//子进程向父进程发送SIGUSR1信号
if(kill(ppid,SIGUSR1)== -1)
{
perror("fail to send signal");
exit(1);
}
while(1);//死循环,等待父进程的信号
}
else
{
sleep(1);//休眠,保证子进程先运行,并且发送SIGUSR1信号
//向子进程发送SIGUSR2信号
if(kill(cpid,SIGUSR2) == -1)
{
perror("fail to send signal");
exit(1);
}
printf("kill child\n");//输出提示信息
if(kill(cpid,SIGKILL)== -1)//发送SIGKILL信号杀死子进程
{
perror("fail to send signal");
exit(1);
}
if(wait(NULL) == -1 )//回收子进程状态,避免僵尸进程
{
perror("fail to wait");
exit(1);
}
}
return 0;
}
- 设置信号信号处理函数void (*signal (int signo ,void (*fun)(int )))(int)
- void (*signal(int signo, void (*fun(int))))(int)
- signal函数的原型声明void (*signal(int signo, void (*fun(int))))(int)分析
- void (*signal(int signo, void (*func) (int))) (int) 理解
- void (*signal (int signo, void (*func)(int))) (int);
- signal函数:void (*signal(int,void(*)(int)))(int);
- 理解(*(void(*)())0)()和void (*signal(int, void(*)(int)))(int)
- signal函数理解或者void (*signal(int signum,void(*handler)(int)))(int)理解
- signal函数理解或者void (*signal(int signum,void(*handler)(int)))(int)理解
- void (*signal(int sig, void (*func) (int))) (int)理解
- void (*signal(int sig, void (*func) (int))) (int)理解
- 对void (*signal(int , void (*) (int))) (int) 理解
- 简化void(*signal(int signum, void(*handler)(int)))(int)
- 有关void (*signl(int signo,void(*func)(int)))(int);的解析
- 关void (*signl(int signo,void(*func)(int)))(int);的解析
- void (*f(int, void (*)(int)))(int) 函数解析
- void (*f(int, void (*)(int)))(int) 函数解析
- void (*f(int, void (*)(int)))(int) 函数解析
- ObservableCollection的泛型查找功能
- Binary Tree Zigzag Level Order Traversal
- 欧拉函数
- C#后台调用前台js方法
- WindowAdapter适配器(一)
- 设置信号信号处理函数void (*signal (int signo ,void (*fun)(int )))(int)
- Unity插件研究院之ResourceChecker
- 黑马程序员之HTML+CSS六
- 《Troubleshooting SQL Server》读书笔记
- 织梦手机模块
- intel c/c++ compiler 下载 安装 编译
- zoj 3725 DP排列
- HDU 4135 Co-prime 数论-求素数对
- [C++基础]019_指针和引用(int*、int&、int*&、int&*、int**)