sigaction函数
sigaction函数的功能是用于改变进程接收到特定信号后的行为。
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
参数
--第一个参数是信号的值,可以为除了SIGKILL及SIGSTOP外的任何一个特定有效的信号(因为这两个信号定义了自己的处理函数,将导致信号安装错误)
--第二个参数是指向节后sigaction的一个实例的指针,在sigaction的实例中,指定了对特定信号的处理,可以为NULL,进程会以缺省方式对信号处理
--第三个参数oldact指向的对象用来保存原来对相应信号的处理,可以为NULL
返回值:函数成功返回0,失败返回-1。

sigaction函数检查或修改与指定信号相关联的处理动作,该函数取代了signal函数。
因为signal函数在信号未决时接收信号可能出现问题,所以使用sigaction更安全。
sigaction结构体
struct sigaction {
void (*sa_handler)(int);//信号处理程序 不接受额外数据
void (*sa_sigaction)(int, siginfo_t *, void *);//信号处理程序,能接受额外数据,可以和sigqueue配合使用
sigset_t sa_mask;

//sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。缺省情况下当前信号本身被阻塞,防止信号的嵌套发送,除非指定SA_NODEFER或者SA_NOMASK标志位。注:请注意sa_mask指定的信号阻塞的前提条件,是在由sigaction()安装信号的处理函数执行过程中由sa_mask指定的信号才被阻塞。

    int        sa_flags;//影响信号的行为SA_SIGINFO表示能接受数据
void (*sa_restorer)(void);//废弃
};
--第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中赢屏蔽掉哪些函数等等。
--回调函数sa_handler、sa_sigaction只能任选其一
/** @file  signalT.cpp
* @note
* @brief
* @author xor
* @date 2019-7-20
* @history
* @warning
*/
//捕捉信号
#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 ;
}
实时信号支持排队不会丢失。(实时信号还有一个特点,即到达的顺序是可以保证的)

sigaction和实时信号sigqueue的更多相关文章

  1. 实时信号与sigqueue函数

    一.sigqueue函数 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用. 原型:int sigqueue(pid_t pid, int s ...

  2. signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数

    信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...

  3. 一款DMA性能优化记录:异步传输和指定实时信号做async IO

    关键词:DMA.sync.async.SIGIO.F_SETSIG. DMA本身用于减轻CPU负担,进行CPU off-load搬运工作. 在DMA驱动内部实现有同步和异步模式,异步模式使用dma_a ...

  4. Linux 改进捕捉信号机制(sigaction,sigqueue)

    sigaction函数 sigaction函数的功能是用于改变进程接收到特定信号后的行为. int sigaction(int signum, const struct sigaction *act, ...

  5. linux系统编程之信号(六):信号发送函数sigqueue和信号安装函数sigaction

    一,sigaction() #include <signal.h> int sigaction(int signum,const struct sigaction *act,struct ...

  6. linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction

    信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...

  7. 信号发送接收函数:sigqueue/sigaction

    信号是一种古老的进程间通信方式,下面的例子利用sigqueue发送信号并附带数据:sigaction函数接受信号并且处理时接受数据. 1.sigqueue: 新的信号发送函数,比kill()函数传递了 ...

  8. signal, sigaction,信号集合操作

    信号是与一定的进程相联系的,而建立其信号和进程的对应关系,这就是信号的安装登记. Linux主要有两个函数实现信号的安装登记:signal和sigaction.其中signal在系统调用的基础上实现, ...

  9. 信号 signal sigaction补充

    目前linux中的signal()是通过sigation()函数实现的. 由signal()安装的实时信号支持排队,同样不会丢失. 先看signal 和 sigaction 的区别: 关键是 stru ...

随机推荐

  1. 如何进行SQL注入攻击?

    1.数字注入 2.字符串注入 3. #后边全部为注释,字符串拼装后绕过密码验证. 4. 同样绕过密码验证

  2. python中str和byte的相互转化

    在涉及到网络传输的时候,数据需要从str转换成btye才能进行传输. python byte 转 str , str 转 byte 其实很简单:原理图如下:在这里插入图片描述案例: a: str = ...

  3. 助教总结---继alpha版本1之后

    本周心得: 在项目的开发当中,学生难免会有懈怠的时候,作为助教更应该去督促和激励同学们,但本质上该对自己负责任的是同学们自己.同学们项目的第一版本已经出来了,这个过程他们自己知道付出了多少,相信他们体 ...

  4. ARTS-week1

    Algorithm 小A 和 小B 在玩猜数字.小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜.他们一共进行三次这个游戏,请返回 小A 猜对了几次? 输入的 ...

  5. go 学习 (二):基本语法

    一.数据类型 布尔型:布尔型的值只可以是常量 true 或者 false.eg:var bo bool = true.布尔型无法参与数值运算,也无法与其他类型进行转换 数字类型:整型 int .浮点型 ...

  6. OLED液晶屏幕(2)取模软件

    https://blog.csdn.net/ling3ye/article/details/53399305 文件夹说明: Adafruit_SSD1306-master   ——SSD1306库(O ...

  7. go的接口内部实现

    1 前言 1.1 Go汇编 Go语言被定义为一门系统编程语言,与C语言一样通过编译器生成可直接运行的二进制文件.这一点与Java,PHP,Python等编程语言存在很大的不同,这些语言都是运行在基于C ...

  8. Maven 打包报错,log4j版本导致

    # 在执行打包的时候 mvn clean assembly:assembly # 发生上面的错误 ------------------------------ [INFO] Total time: 2 ...

  9. 搭建Portainer可视化界面

    1.下载Portainer镜像 docker pull portainer/portainer 2.安装分为单机版及集群版 2.1单机版安装 docker run -d -p 9000:9000 \- ...

  10. HTTP与RPC(Thrift)

    什么是RPC 从网络协议来说,Http协议与Rpc同属于应用层, 他们的底层都是tcp协议. RPC(即Remote Procedure Call,远程过程调用)和HTTP(HyperText Tra ...