Linux 改进捕捉信号机制(sigaction,sigqueue)
sigaction函数
sigaction函数的功能是用于改变进程接收到特定信号后的行为。
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
参数
--第一个参数是信号的值,可以为除了SIGKILL及SIGSTOP外的任何一个特定有效的信号(因为这两个信号定义了自己的处理函数,将导致信号安装错误)
--第二个参数是指向节后sigaction的一个实例的指针,在sigaction的实例中,指定了对特定信号的处理,可以为NULL,进程会以缺省方式对信号处理
--第三个参数oldact指向的对象用来保存原来对相应信号的处理,可以为NULL
返回值:函数成功返回0,失败返回-。
sigaction函数检查或修改与指定信号相关联的处理动作,该函数取代了signal函数。
因为signal函数在信号未决时接收信号可能出现问题,所以使用sigaction更安全。
sigaction结构体
struct sigaction {
void (*sa_handler)(int);//信号处理程序 不接受额外数据
void (*sa_sigaction)(int, siginfo_t *, void *);//信号处理程序,能接受额外数据,可以和sigqueue配合使用
sigset_t sa_mask;
int sa_flags;//影响信号的行为SA_SIGINFO表示能接受数据
void (*sa_restorer)(void);//废弃
};
--第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中赢屏蔽掉哪些函数等等。
--回调函数sa_handler、sa_sigaction只能任选其一
//捕捉信号
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h> void catch_signal(int sign)
{
switch(sign)
{
case SIGINT:
//SIGINT默认行为是退出进程
printf("SIGINT signal\n");
exit();
break;
case SIGALRM:
//SIGALRM默认行为是退出进程
printf("SIGALRM signal\n");
break;
case SIGKILL:
printf("SIGKILL signal\n");
break;
}
} //建议使用封装之后的mysignal
int mysignal(int sign,void (*func)(int))
{
struct sigaction act,oact;
//传入回调函数
act.sa_handler=func;
//将act的属性sa_mask设置一个初始值
sigemptyset(&act.sa_mask);
act.sa_flags=;
return sigaction(sign,&act,&oact);
} int main(int arg, char *args[])
{
mysignal(SIGINT,catch_signal);
mysignal(SIGALRM,catch_signal);
mysignal(SIGKILL,catch_signal);
int i=;
while()
{
printf("hello god %d\n",i++);
sleep();
}
return ;
}
sigqueue函数
--新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与sigaction()函数配合使用
--注意:和kill函数相比int kill(pid_t pid,int signo)多了参数
--原型 int sigqueue(pid_t pid,int signo,const union sigval value);
--参数 sigqueue的第一个参数是指定接收信号的进程pid,第二个参数确定即将发送的信号,
第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。
--函数成功返回0,失败返回-1,并且更新errno
--sigqueue()比kill()传递了更多的附加信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组
--union sigval联合体
typedef union sigval
{
int sival_int;
void * sival_ptr;
}sigval_t;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
/*
siginfo_t {
int si_signo; // Signal number
int si_errno; // An errno value
int si_code; // Signal code
int si_trapno; // Trap number that caused
hardware-generated signal
(unused on most architectures)
pid_t si_pid; // Sending process ID
uid_t si_uid; // Real user ID of sending process
int si_status; // Exit value or signal
clock_t si_utime; // User time consumed
clock_t si_stime; // System time consumed
sigval_t si_value; // Signal value
int si_int; // POSIX.1b signal
void *si_ptr; // POSIX.1b signal
int si_overrun; // Timer overrun count; POSIX.1b timers
int si_timerid; // Timer ID; POSIX.1b timers
void *si_addr; // Memory location which caused fault
int si_band; // Band event
int si_fd; // File descriptor
} */ void catch_signal(int signo,siginfo_t *resdata,void *unkonwp)
{
printf("signo=%d\n",signo);
printf("return data :%d\n",resdata->si_value.sival_int);
printf("second return data:%d\n",resdata->si_int);
return ;
} int main(int arg, char *args[])
{
pid_t pid=;
pid=fork();
if(pid==-)
{
printf("fork() failed! error message:%s\n",strerror(errno));
return -;
}
if(pid==)
{
printf("i am child!\n");
//等待父进程执行完信号安装
sleep();
//向父进程发送带数据的信号
union sigval sigvalue;
sigvalue.sival_int=;
//发送信号
if(sigqueue(getppid(),SIGINT,sigvalue)==-)
{
printf("sigqueue() failed ! error message:%s\n",strerror(errno));
exit();
}
printf("子进程信号发送成功!\n");
exit();
}
if(pid>)
{
printf("i am father!\n");
//安装信号
struct sigaction act;
//初始化sa_mask
sigemptyset(&act.sa_mask);
act.sa_sigaction=catch_signal;
//一旦使用了sa_sigaction属性,那么必须设置sa_flags属性的值为SA_SIGINFO
act.sa_flags=SA_SIGINFO;
//安装信号
if(sigaction(SIGINT,&act,NULL)!=)
{
printf("sigaction() failed! \n");
return -;
}
//等待子进程返回
int status=;
wait(&status);
printf("game over!\n");
}
return ;
}
Linux 改进捕捉信号机制(sigaction,sigqueue)的更多相关文章
- linux下 signal信号机制的透彻分析与各种实例讲解
转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/det ...
- Linux下的信号机制
2017-04-06 之前在看LinuxThreads线程模型的时候,看到该模型是通过信号实现线程间的同步,当时没有多想,直接当做信号量了,现在想起来真是汗颜……后来想想并不是那么回事,于是,就有了今 ...
- linux中的信号机制
概述 Linux信号机制是在应用软件层次上对中断机制的一种模拟,信号提供了一种处理异步事件的方法,例如,终端用户输入中断键(ctrl+c),则会通过信号机制停止一个程序[1]. 这其实就是向那个程序( ...
- Linux下捕捉信号
关于 信号signal的知识铺垫 点这里 信号由三种处理方式: 忽略 执行该信号的默认处理动作 捕捉信号 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个自定义函数,这称为捕捉信号. 进程收 ...
- linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction
一,sigaction() #include <signal.h> int sigaction(int signum,const struct sigaction *act,struct ...
- linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction
信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...
- Linux信号机制
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- xenomai内核解析之信号signal(一)---Linux信号机制
版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
随机推荐
- UINavigationBar 和 UINavigationItem的属性设置
#import "RootViewController.h" @interface RootViewController () @end @implementation RootV ...
- 【原】iOSCoreAnimation动画系列教程(二):CAKeyFrameAnimation【包会】
在上一篇专题文章[原]iOSCoreAnimation动画系列教程(一):CABasicAnimation[包会]中我们学习了iOS核心动画CoreAnimation中CABasicAnimation ...
- windows phone(成语典籍游戏开发)
- C语言-09-文件操作
文件类型 文本文件(ASCII) 简单的文本文件,可用任何文字处理程序阅读 二进制文件 包含 在ASCII及扩展ASCII字符中编写的数据或程序指令 的文件,通常图形文件及文字处理程序等计算机程序都属 ...
- Android 之 2048 的游戏逻辑分析
继续学习了极客学院的实战路径课程,讲到了2048游戏的编写过程,我在这里作个总结分享给大家(结果会附源代码和我改写后的代码): 这里主要包括两个方面:1.2048界面的绘制 2.2048算法逻辑的 ...
- scanf 用法及陷阱(转)
函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设备( ...
- Effective Java 61 Throw exceptions appropriate to the abstraction
Exception translation: higher layers should catch lower-level exceptions and, in their place, throw ...
- 【同步复制常见错误处理3】找不到存储的过程 sp_MSins_tablename
环境在SQL2008 R2同步复制时出错 这个错误提示是由于在订阅端没有找到同步时调用的同步存储过程,MS错误说明: 当某个事务发布在 SQL SERVER自动同步设置选择订阅服务器插入. 更新和删除 ...
- hdu 4738 Caocao's Bridges 图--桥的判断模板
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Linux syslog介绍
一.简介 syslog是Linux系统默认的日志守护进程.默认的主配置文件和辅助配置文件分别是/etc/syslog.conf和/etc/sysconfig/syslog文件.通常,syslog 接受 ...