在7.10节中,我们讲述了setjmp以及longjmp函数,这两个函数用于远程跳转。其中longjmp函数进场在信号处理函数中被调用,用于返回到进程的主循环中去,而不是从信号处理函数中返回。
但是使用函数longjmp有一个问题,当一个信号被捕获的时候,信号处理函数被执行,当前信号将被自动增加到进程的信号掩码中去。这样做的目的是为了防止后续的信号中断当前信号处理函数的执行,如果我们调用longjmp函数退出信号处理函数,信号掩码将会发生什么呢?

在FreeBSD 8.0以及Mac OS X 10.6.8中,setjmp以及longjmp函数保存和恢复信号掩码,Linux 3.2.0以及Solaris 10并没有这么做,虽然Linux支持通过选项来提供BSD的行为。FreeBSD以及Mac OS X提供了函数_setjmp以及_longjmp函数,这两个函数并不保存和恢复信号掩码。
为了允许两种行为方式,POSIX.1并没有指定setjmp和longjmp函数的对于信号掩码的影响,取而代之的是,增加了两个新函数sigsetjmp以及siglongjmp函数,当从信号处理函数中进行跳转的时候一定要使用这两个函数。

  1. #include <setjmp.h>
  2. int sigsetjmp(sigjmp_buf env, int savemask);
  3. Returns:0 if called directly,nonzero if returning from a call to siglongjmp
  4. void siglongjmp(sigjmp_buf env, int val);

这两个函数与setjmp和longjmp函数的差异就是sigsetjmp有一个额外的参数。当参数savemask是非零数值的时候,sigsetjmp会将当前信号掩码一起去保存到env中,当siglongjmp函数被调用的时候,如果sigsetjmp调用的时候使用的是非零的savemask来保存的env.那么siglongjmp函数就会恢复已经保存的信号掩码。

example

  1. #include "apue.h"
  2. #include <setjmp.h>
  3. #include <time.h>
  4. static void sig_usr1(int);
  5. static void sig_alarm(int);
  6. static sigjmp_buf jmpbuf;
  7. static volatile sig_atomic_t canjump;
  8. int main(void)
  9. {
  10. if(signal(SIGUSR1, sig_usr1) == SIG_ERR)
  11. err_sys("signal(SIGUSR1) error");
  12. if(signal(SIGALRM, sig_alarm) == SIG_ERR)
  13. err_sys("signal(SIGALRM) error");
  14. pr_mask("starting main: "); /* Figure 10.14 */
  15. if(sigsetjmp(jmpbuf, 1))
  16. {
  17. pr_mask("ending main: ");
  18. exit(0);
  19. }
  20. canjump = 1; /*now sigsetjmp() is OK*/
  21. for(;;)
  22. pause();
  23. }
  24. static void sig_usr1(int signo)
  25. {
  26. time_t starttime;
  27. if(canjump == 0)
  28. return; /*unspected signal, ignore */
  29. pr_mask("starting sig_usr1: ");
  30. alarm(3); /*SIGALRM in 3 seconds */
  31. starttime = time(NULL);
  32. for(;;)
  33. {
  34. if(time(NULL) > starttime+5)
  35. break;
  36. }
  37. pr_mask("finishing sig_usr1: ");
  38. canjump = 0;
  39. siglongjmp(jmpbuf, 1); /* jump back to main, don't return */
  40. }
  41. static void sig_alarm(int signo)
  42. {
  43. pr_mask("in sig_alarm: ");
  44. }

执行效果如下所示:

  1. os@debian:~/UnixProgram/Chapter10$ ./10_20.exe &
  2. [3] 2566
  3. os@debian:~/UnixProgram/Chapter10$ starting main: over
  4. kill -USR1 2566
  5. starting sig_usr1: SIHUSR1 over
  6. os@debian:~/UnixProgram/Chapter10$ in sig_alarm: SIHUSR1 SIGALRM over
  7. finishing sig_usr1: SIHUSR1 over
  8. ending main: over
  9. [3]+ Done ./10_20.exe
  10. os@debian:~/UnixProgram/Chapter10$
来自为知笔记(Wiz)

转载于:https://www.cnblogs.com/U201013687/p/5518366.html

10.15 sigstjmp以及siglongjmp函数相关推荐

  1. Python数据分析 1-5 NumPy中ufunc函数(一)主要介绍NumPy中常用的通用函数:基本数学函数、三角函数和反三角函数和统计类函数

    1 引入NumPy #引入numpy import numpy as np np.__version__ '1.20.1' 2 基本数学函数 NumPy中基本数学函数有加法.减法.乘法.除法.乘方.开 ...

  2. 修改COCO评价指标 maxDets=[10,15,20]

    默认的COCO评价指标 maxDets=[1,10,100] 该指标的意思是分别保留测试集的每张图上置信度排名第1.前10.前100个预测框,根据这些预测框和真实框进行比对,来计算AP.AR等值(有点 ...

  3. Python 最近两条好消息:①TIOBE排名超过C和Java②新版本发布3.10.0,还有今天刚发布的《What’s New in Python(2021.10.15)》

    来自TIOBE的最新10月份统计数据显示,Python首次超越Java.JavaScript.C语言等,成为最受欢迎的编程语言.TIOBE过去20年一直在追踪编程语言的受欢迎程度,其数据来自于对25个 ...

  4. MacOS 10.15 Laravel框架 使用 Box/Spout 导入导出Excel

    MacOS 10.15 Laravel框架 使用 Box/Spout 导入导出Excel 准备工作 环境条件 安装Composer 使用Composer安装 Box/Spout 导入Excel 官方描 ...

  5. Mac 10.15之后版本系统Gomonkey错误解决

    Mac 10.15之后版本系统Gomonkey错误解决 前景:在写单元测试的时候,利用gomonkey框架打桩方法函数的时候,出现了如下问题: Line 81: - permission denied ...

  6. Excel公式=SUM(COUNTIF(data,{10,15})*{1,-1})的含义

    iamlaosong文 在介绍countif函数的用法中涉及双条件时一般都有下面的例子: 两个条件求个数(其中data是范围,比如A1:A100) (1) >10并且<=15 =SUM(C ...

  7. 项目需求|10~15万|自动上料系统—将物料通过机械手臂挂在挂钩上

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 项目需求: 自动上料系统(将物料通过机械手臂挂在挂钩上) 需求内容: 1.利用3D视觉技术(点云配置或 ...

  8. 虚拟机中的黑苹果系统经常卡死_程序员吐槽macOS 10.15系统:破坏SSH默认规则

    晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI 苹果电脑最新的10.15.4系统,你更新了吗? 如果你不幸升级,而且还是要使用SSH的用户,那么恭喜你中招了. 最近,一位名叫Taylor ...

  9. 电动力学每日一题 2021/10/15 Fourier变换法计算均匀电流密度产生的磁场

    电动力学每日一题 2021/10/15 Fourier变换法计算均匀电流密度产生的磁场 无限长均匀电流 无限长圆柱面均匀电流密度 无限长均匀电流 假设z轴上有一根非常细的电线,携带均匀电流I0I_0I ...

最新文章

  1. git获取指定release版本代码
  2. namesapce的作用 增加访问路径 目的:区分不同包的相同action的访问路径
  3. mysql 恢复root用户_mysql误删root用户恢复方案
  4. 数据结构与算法--简单栈实现及其应用
  5. JavaOne和OOW 2015总结
  6. JAVA中基本类型Boolean占几个字节
  7. 解决JAVA_HOME nor the JRE_HOME environment variable is defined
  8. c语言循环结构菱形九九乘法表,C语言基础用基本的循环语句打印实心和空心菱形、九九乘法表 ....
  9. 常用正则表达式锦集与Python中正则表达式的用法
  10. SAP License:两种不太常见的移动类型
  11. 如何在Exchange中处理不能发送的信息
  12. java与模式观察者模式_谈谈java中的观察者模式
  13. miui国际版/波兰版 开通公交卡 / 模拟门禁卡
  14. 本地图片转换Base64的方法,Base64码转换为本地图片
  15. 永远的疯狂竹子----纪念退役不久的V-Gundam
  16. LGB、XGB、CBT参数
  17. 机器学习——聚类分析
  18. mixwit怀旧磁带音乐盒
  19. python 列表 常用操作 列表的循环遍历
  20. Java基础练习——读心术(扑克牌魔术——21张扑克牌)

热门文章

  1. 全国各地 DNS 服务器 IP 总汇
  2. 两次被简书签约作者拉黑的经历
  3. 开源GIS(十三)——openlayers通过geoserver中WFS添加要素
  4. 将运行时地理数据库(*.geodatabase)复制到文件地理数据库
  5. MemCache详细介绍
  6. linux c++ sqlite_SQLite 真的很容易编译 | Linux 中国
  7. Maven阿里云镜像配置
  8. hadoop 修复hdfs中文件块错误 和文件修复 Error: java.io.IOException: Cannot obtain block length for LocatedBlock
  9. 如何动态的修改隐藏域,让它实现添加,又可以实现修改操作
  10. 乐视android系统耗电量大,乐视手机突然充电慢耗电快,怎么解决?