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的调试相对比较方便,因为可以通过 ...
随机推荐
- MongoDB 的 GridFS 详细分析
GridFS简介 GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件. http://www.mongodb.org/display/DOCS/GridFS http://www.m ...
- python 连接 db2
export IBM_DB_DIR=/home/db2inst1/sqllib export IBM_DB_LIB=/home/db2inst1/sqllib/lib http://programmi ...
- 第k大的数,前k大的数
1.排序后去出前k个,o(n*log(n)) 如果k<log(n),可以考虑直接选择排序,因为只需要执行找到第k个就可以结束 o(n*k) 2.o(nlog(k))快排把数分为了两个部分, ...
- python基本数据结构-集合-集合运算
- 学习调用WCF服务的各种方法
1.开发工具调用WCF 这中方法很方便也很简单,很多工作VS就帮我们完成了.相信大家也不会对这种方法陌生.这里简单提一下.打开VS,在项目中添加服务引用: 在config中自动声明了有关服务的节点信息 ...
- cocos2d-x之Vector与map
bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...
- Java API 快速速查宝典
Java API 快速速查宝典 作者:明日科技,陈丹丹,李银龙,王国辉 著 出版社:人民邮电出版社 出版时间:2012年5月 Java编程的最基本要素是方法.属性和事件,掌握这些要素,就掌握了解决实际 ...
- MyEclipse10 离线图文安装SVN插件教程
一.下载SVN插件subclipse 1.下载 下载地址:http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 ...
- Linux LDAP Server--->Clients配置
Linux Ldap Configuration LDAP Server Base Software & SysTem Info SysTem Info 系统版本:centos 6.4 LDA ...
- Linux nmap
一.简介 Nmap(Network Mapper)是一款开放源代码的网络探测和安全审核工具.它用于快速扫描一个网络和一台主机开放的端口,还能使用TCP/IP协议栈特征探测远程主机的操作系统类型.nma ...