信号是一种古老的进程间通信方式,下面的例子利用sigqueue发送信号并附带数据;sigaction函数接受信号并且处理时接受数据。

1、sigqueue: 新的信号发送函数,比kill()函数传递了更多附加信息,但它只能向一个进程发送信号,针对实时信号(支持排队不会丢失),与sigaction配合使用。
  int sigqueue(pid_t pid, int sig, const union sigval value);

  typedef union sigval
  {
    int sival_int;
    void *sival_ptr;
  }sigval_t;

其中第一个参数指接收信号的进程ID;第二个参数确定即将发送的信号;第三个参数指定了信号传递的参数(可用于进程间通信,传递附带数据)。函数成功返回0,失败返回-1。

2、sigaction函数可以用来接受信号进行信号处理

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  struct  sigaction{
    void (*sa_handler)(int);
    sigset_t sa_mask;
    int sa_flag;//接收数据
    void (*sa_sigaction)(int,siginfo_t*,void*);
  };

  结构体sigaction中的sa_flags字段等于SA_SIGINFO时可以接受数据。而void (*sa_sigaction)(int,siginfo_t*,void*)函数指针的参数结构体如下:
  struct siginfo{
    int si_signo;
    int si_error;
    .
    .
    .
    union sigval si_value;//包含两个字段(int sival_int ;void *sival_ptr)

    int  si_int;  //同时,如果传递的是整数字段,也会传递到si_int中

    void *si_ptr; //如果是指针字段,也会传递到si_ptr中

    .

    .
  }
  这个结构体中的si_value对应的就是sigqueue发送过来的union sigval

  这个例子是两个进程之间信号传递数据的例子:

第一个程序是利用sigqueue向特定进程发送信号和数据的程序.这个程序接受一个进程号作为参数

 1 #include<unistd.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include<string.h>
9
10 #include<signal.h>
11 #define ERR_EXIT(m)\
12 do\
13 {\
14 perror(m);\
15 exit(EXIT_FAILURE);\
16 }while(0) //宏要求一条语句
17 int main(int argc,char*argv[])
18 {
19 if(argc!=2){
20 fprintf(stderr,"Usage %s pid\n",argv[0]);
21 exit(EXIT_FAILURE);
22 }
23 pid_t pid=atoi(argv[1]);
24 union sigval v;
25 v.sival_int=100;
26 sigqueue(pid,SIGINT,v);
27 return 0;
28 }

接下来的进程是对应上面程序的接受信号的程序,这个程序利用sigaction函数的中的信号处理程序处理信号和数据,先运行这个程序,然后上一个程序可以向这个进程发送信号:

 1 #include<unistd.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include<string.h>
9
10 #include<signal.h>
11 #define ERR_EXIT(m)\
12 do\
13 {\
14 perror(m);\
15 exit(EXIT_FAILURE);\
16 }while(0) //宏要求一条语句
17 void handler(int sig,siginfo_t* info,void* ctx);
18 int main(int argc,char*argv[])
19 {
20 struct sigaction act;
21 act.sa_sigaction=handler;//不能使用sa_handler函数了,要使用 void (*sa_sigaction) (int,siginfo_t*,void*)
22 sigemptyset(&act.sa_mask);
23 act.sa_flags=SA_SIGINFO;//指定sa_flags传递数据
24 if(sigaction(SIGINT,&act,NULL)<0)
25 ERR_EXIT("sigaction error\n");
26 for(;;)
27 pause();
28 return 0;
29 }
30
31 void handler(int sig,siginfo_t* info,void* ctx)
32 {
33 printf("receive a sig=%d\n,data=%d\n",sig,info->si_value.sival_int);
34
35 }

信号发送接收函数:sigqueue/sigaction的更多相关文章

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

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

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

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

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

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

  4. APUE学习笔记——10.9 信号发送函数kill、 raise、alarm、pause

    转载注明出处:Windeal学习笔记 kil和raise kill()用来向进程或进程组发送信号 raise()用来向自身进程发送信号. #include <signal.h> int k ...

  5. 信号处理函数(3)-sigaction() 为信号注册信号捕捉函数

    定义: int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact); 表头文件: #include& ...

  6. QT槽函数获取信号发送对象

    Qt 在槽函数中获取信号发送对象 Qt中提供了一个函数 qobject_cast(QObject *object),可以通过这个函数判断信号发出对象 Qt 帮助文档的解释: Returns the g ...

  7. PyQt学习随笔:槽函数获取信号发送对象的方法

    在PyQt中,相似控件发送的信号可以每个控件信号对应一个槽函数,也可以将相似控件的相同信号对应到一个槽函数,但如果槽函数相同,怎么区分信号是谁发送的呢?那就是在信号函数中使用sender()函数获取信 ...

  8. 信号之sigsuspend函数

    更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞.使用这种技术可以保护不希望由信号中断的代码临界区.如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,则又将如何呢?假定信 ...

  9. 信号之abort函数

    abort函数的功能是使异常程序终止. #include <stdlib.h> void abort(void); 此函数不返回 此函数将SIGABRT信号发送给调用进程(进程不应忽略此信 ...

随机推荐

  1. 多测师讲解接口测试 _linux中搭建环境cms_高级讲师肖sir

    cms后台的搭建, 我们主要是用来做接口测试和接口自动化测试: 我们搭建的流程和之前搭建多有米一样: 后期给我们一个war包就要知道搭建一个文档: 要知道环境项目怎么讲?   讲解下搭建cms环境的流 ...

  2. rs232转以太网转换器

    rs232转以太网转换器 rs232转网络ZLAN5103可以实现RS232/485/422和TCP/IP之间进行透明数据转发.方便地使得串口设备连接到以太网和Internet,实现串口设备的网络化升 ...

  3. day11 Pyhton学习

    一.昨日内容回顾 函数的进阶 动态传参 *args : 位置参数的动态传参 **kwargs: 关键字参数的动态传参 形参:聚合 实参:打散 顺序:位置参数>*args >默认值 > ...

  4. 用python you-get下载视频

    安装python3后 安装you-get包: pip3 install you-get 下载视频: 打开windows终端:运行 you-get url 查看视频信息: you-get -i url ...

  5. 【暑假集训】HZOI2019 水站 多种解法

    题目内容 已知有一个\(n\)层的水站: \(W_i\)表示未操作之前第\(i\)层的已有水量: \(L_i\)表示第\(i\)个水站能够维持或者储存的水的重量: 表示在第\(P_i\)层进行减压放水 ...

  6. filebeat- 配置

    wget https://mirrors.huaweicloud.com/filebeat/7.9.1/filebeat-7.9.1-linux-x86_64.tar.gz tar -zxvf fil ...

  7. es 讲义

    链接: https://pan.baidu.com/s/193jObXs85OZcvAHDycUXlw 提取码: ewbp

  8. HTML轮播(2)

    前言 现在在完成轮播的框架上进行扩展更多的功能,上下切换图片,以及添加动画滚动更加平滑过渡 CSS <style> #LB { width: 100%; height: 948px; ov ...

  9. java面试题目之JVM(YW制作仅供参考)

    1.JVM工作原理 2.JVM组成部分及其作用. java虚拟机分为两个子系统和两个组件. 两个子系统分别是类加载器和执行引擎,类加载器负责加载字节码(.class)文件到JVM的内存中,执行引擎负责 ...

  10. 010_Java历史及特性

    目录 Java历史 C语言 1972年 C++ 1982年 Java 1995年 Applet 图形界面的程序 J2SE Java 2 标准版 桌面 J2ME Java 2 移动版 手机 J2EE J ...