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. PHP-FPM的知识点

    https://blog.csdn.net/resilient/article/details/82420863 这个URL,将php的各种模式与知识点说清楚了. 因为php-fpm默认编译进了php ...

  2. Strength(HDU6563+2018年吉林站+双指针瞎搞)

    题目链接 传送门 题意 你有\(n\)只怪,每只怪的伤害为\(a_i\),对手有\(m\)只怪,每只怪的伤害为\(b_i\),对手的怪有普通状态和防守状态(普通状态:如果你用攻击力为\(a_i(a_i ...

  3. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  4. 运维笔试Python编程题

    一.用Python语言把列表[1,3,5,7,9]倒序并将元素变为字符类型,请写出多种方法: 第一种方法: list = [1, 3, 5, 7, 9] list.reverse() list2 = ...

  5. Tomcat项目内存参数调优

    一.常见的Java内存溢出有以下三种: 1. Java.lang.OutOfMemoryError: Java heap space 即JVM Heap溢出 解释说明:JVM在启动的时候会自动设置JV ...

  6. HDU - 5571 :tree (动态点分治 异或)

    题意:给定一棵树,有点权a[],有边权. 现在有M次修改点权的操作,输出每次修改后,Σ(a[i]^a[j])*dis(i,j); 思路:因为待修改,我们需要快速得到以及修改一个点到其他所有点的信息. ...

  7. Linux——CentOS7没有第二张网卡的配置信息

    前言 为了一个实验做测试,在VMware中配置了环境,但是配置了双网卡后发现第二张网卡没有配置文件. 都是些基本命令就不写了,图里也有. 系统 : CentOS7.6 步骤 查看网卡信息 使用ip a ...

  8. C#笔记2 —常量

    基本上和c语言中的常量类似,但有区别 在const关键字的基础上,添加了readonly,readonly关键字在笔记中说明. 常量是固定值,程序执行期间不会改变.常量可以是任何基本数据类型,比如整数 ...

  9. npm run dev 报错 iview TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

    运行npm run dev报这个错 然后找到 D:\text\vue\iview-admin\build\webpack.dev.config.js打开 将这一行代码: fs.write(fd, bu ...

  10. screen对象及属性(availWidth、availHeight)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...