我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程。那么我们应该如何设定我们需要处理的信号,我们不需要处理哪些信号等问题呢?信号集函数就是帮助我们解决这些问题的。
 
有关Linux进程间使用信号通信的更多内容,可以参阅我的另一篇文章——Linux进程间通信——使用信号
 
下面是信号函数集:
1、int sigemptyset(sigset_t *set);
该函数的作用是将信号集初始化为空。
 
2、int sigfillset(sigset_t *set);
该函数的作用是把信号集初始化包含所有已定义的信号。
 
3、int sigaddset(sigset_t *set, int signo);
该函数的作用是把信号signo添加到信号集set中,成功时返回0,失败时返回-1。
 
4、int sigdelset(sigset_t *set, int signo);
该函数的作用是把信号signo从信号集set中删除,成功时返回0,失败时返回-1.
 
5、int sigismember(sigset_t *set, int signo);
该函数的作用是判断给定的信号signo是否是信号集中的一个成员,如果是返回1,如果不是,返回0,如果给定的信号无效,返回-1;
 
6、int sigpromask(int how, const sigset_t *set, sigset_t *oset);
该函数可以根据参数指定的方法修改进程的信号屏蔽字。新的信号屏蔽字由参数set(非空)指定,而原先的信号屏蔽字将保存在oset(非空)中。如果set为空,则how没有意义,但此时调用该函数,如果oset不为空,则把当前信号屏蔽字保存到oset中。
 
how的不同取值及操作如下所示:
如果sigpromask成功完成返回0,如果how取值无效返回-1,并设置errno为EINVAL。
 
注意:调用这个函数才能改变进程的屏蔽字,之前的函数都是为改变一个变量的值而已,并不会真正影响进程的屏蔽字。
 
7、int sigpending(sigset_t *set);
该函数的作用是将被阻塞的信号中停留在待处理状态的一组信号写到参数set指向的信号集中,成功调用返回0,否则返回-1,并设置errno表明错误原因。
 
8、int sigsuspend(const sigset_t *sigmask);
该函数通过将进程的屏蔽字替换为由参数sigmask给出的信号集,然后挂起进程的执行。注意操作的先后顺序,是先替换再挂起程序的执行。程序将在信号处理函数执行完毕后继续执行。如果接收到信号终止了程序,sigsuspend就不会返回,如果接收到的信号没有终止程序,sigsuspend就返回-1,并将errno设置为EINTR。
 
特别提醒:如果一个信号被进程阻塞,它就不会传递给进程,但会停留在待处理状态,当进程解除对待处理信号的阻塞时,待处理信号就会立刻被处理。
 
下面以一个例子来说明上述函数的用法,源文件为sigset.c,代码如下:
 
  1. #include <unistd.h>
  2. #include <signal.h>
  3. #include <sys/types.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. void handler(int sig)
  7. {
  8. printf("Handle the signal %d\n", sig);
  9. }
  10. int main()
  11. {
  12. sigset_t sigset;//用于记录屏蔽字
  13. sigset_t ign;//用于记录被阻塞的信号集
  14. struct sigaction act;
  15. //清空信号集
  16. sigemptyset(&sigset);
  17. sigemptyset(&ign);
  18. //向信号集中添加信号SIGINT
  19. sigaddset(&sigset, SIGINT);
  20. //设置处理函数和信号集
  21. act.sa_handler = handler;
  22. sigemptyset(&act.sa_mask);
  23. act.sa_flags = 0;
  24. sigaction(SIGINT, &act, 0);
  25. printf("Wait the signal SIGINT...\n");
  26. pause();//挂起进程,等待信号
  27. //设置进程屏蔽字,在本例中为屏蔽SIGINT
  28. sigprocmask(SIG_SETMASK, &sigset, 0);
  29. printf("Please press Ctrl+c in 10 seconds...\n");
  30. sleep(10);
  31. //测试SIGINT是否被屏蔽
  32. sigpending(&ign);
  33. if(sigismember(&ign, SIGINT))
  34. printf("The SIGINT signal has ignored\n");
  35. //在信号集中删除信号SIGINT
  36. sigdelset(&sigset, SIGINT);
  37. printf("Wait the signal SIGINT...\n");
  38. //将进程的屏蔽字重新设置,即取消对SIGINT的屏蔽
  39. //并挂起进程
  40. sigsuspend(&sigset);
  41. printf("The app will exit in 5 seconds!\n");
  42. sleep(5);
  43. exit(0);
  44. }
运行结果如下:
首先,我们能过sigaction函数改变了SIGINT信号的默认行为,使之执行指定的函数handler,所以输出了语句:Handle the signal 2。然后,通过sigprocmask设置进程的信号屏蔽字,把SIGINT信号屏蔽起来,所以过了10秒之后,用sigpending函数去获取被阻塞的信号集时,检测到了被阻塞的信号SIGINT,输出The SIGINT signal has ignored。最后,用函数sigdelset函数去除先前用sigaddset函数加在sigset上的信号SIGINT,再调用函数sigsuspend,把进程的屏蔽字再次修改为sigset(不包含SIGINT),并挂起进程。由于先前的SIGINT信号停留在待处理状态,而现在进程已经不再阻塞该信号,所以进程马上对该信号进行处理,从而在最后,你不用输入Ctrl+c也会出现后面的处理语句(可参阅前面特别提醒的内容),最后过了5秒程序就成功退出了。

Linux-进程间的通信-信号集函数【转】的更多相关文章

  1. Linux进程间的通信

    一.管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: A. 管道是半双工的,数据只能向一个方向流动: B. 需要双工通信时,需要建立起两个管道: C. 只能用于父子进程或者兄弟 ...

  2. PHP与Linux进程间的通信

    进程间通信预计是公司考察应届毕业生的必考点(嵌入式行业).当然非常多公司考的是算法. 不查阅资料,我脑子里能想到的 [1] 管道, (有名.无名) [2] 父子进程 [3] System V (消息队 ...

  3. Linux Linux程序练习十六(进程间的通信信号版)

    /* * 题目: * 编写程序,要去实现如下功能: 父进程创建子进程1和子进程2.子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2; 子进程2接受可靠信号的值,并发送给父进程,父进 ...

  4. linux进程间的通信之 共享内存

    一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的 ...

  5. linux进程间的通信方式

    linux进程间的通信 进程间的通信就是不同的进程之间传播或交换信息,进程的用户空间是互相独立,进程之间可以利用系统空间交换信息. 管道 允许将一个进程的标准输出和另一个进程的标准输入连接在一起,主要 ...

  6. c++ 网络编程(三) LINUX/windows 进程间的通信原理与实现代码 基于多进程的服务端实现

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9613027.html 锲子:进程与线程是什么,他们的区别在哪里: 1 进程概念 进程是程序的一 ...

  7. c 进程间的通信

    在上篇讲解了如何创建和调用进程 c 进程和系统调用 这篇文章就专门讲讲进程通信的问题 先来看一段下边的代码,这段代码的作用是根据关键字调用一个Python程序来检索RSS源,然后打开那个URL #in ...

  8. Linux 进程间通讯

    一.Linux 下进程间通讯方式 1)管道(Pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  9. posix进程间的通信

    1.无名管道 1.1管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: 只能用于父子进程或者兄弟进程之间( ...

随机推荐

  1. contenttypes - django组件

    一.contenttypes介绍 它的作用:可以通过两个字段让表和N张表创建FK关系 二.ContentType.GenericForeignKey.GenericRelation 表结构: from ...

  2. 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ

    正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...

  3. 新建的web工程找不到javax.servlet.http.httpservlet

    1.在出现此错误的项目上右键-->Build Path --> Configure Build Path 2.点击右边的 ADD Library 3.选中“Server Runtime”, ...

  4. oracle(九)索引扫描

    (1)索引唯一扫描(index unique scan) (2)索引范围扫描(index range scan) (3)索引全扫描(index full scan) (4)索引快速扫描(index f ...

  5. 如何使用Soft-NMS实现目标检测并提升准确率

    非极大值抑制(Non-Maximum suppression,NMS)是物体检测流程中重要的组成部分.它首先基于物体检测分数产生检测框,分数高的检测框M被选中,其他与被选中检测框又明显重叠的检测框被抑 ...

  6. 理解SQL Server中索引的概念,原理

    转自:http://www.cnblogs.com/CareySon/archive/2011/12/22/2297568.html 简介 在SQL Server中,索引是一种增强式的存在,这意味着, ...

  7. 最强Mac电脑 工作站级别一体机iMac Pro公布

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/a2Ni5KFDaIO1E6/article/details/78795857 前不久传出消息,苹果将 ...

  8. PHP开启CORS

    CORS 定义 Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 ...

  9. 梯度下降法实现-python[转载]

    转自:https://www.jianshu.com/p/c7e642877b0e 梯度下降法,思想及代码解读. import numpy as np # Size of the points dat ...

  10. html03

    快速开发指南:1.新建页面之后,编写外部样式表文件,引入到HTML页面中2.用浏览器打开页面->F12->sources->打开css文件 右边编写样式,左边查看效果3.样式编写完成 ...