信号驱动任务执行(pause、sigsuspend函数)

news2024/11/20 10:31:19

信号驱动任务指的是通过信号来驱动任务的执行,每发送一次信号,任务就执行一次。实现该目的所需的函数就是 pause 或者 sigsuspend,pause和sigsuspend函数可以暂停当前进程,直至收到信号才会继续运行之后的程序。


目录

1、认识 pause / sigsuspend 函数

(1) pause 函数

(2) sigsuspend 函数

2、信号驱动任务执行的两种方式

(1) sigprocmask + pause

(2) sigsuspend


1、认识 pause / sigsuspend 函数

(1) pause 函数

pause 函数的作用是暂停当前进程(进入休眠状态),直至收到信号(任意信号),才会唤醒当前进程。

因为信号的处理动作有终止、忽略、捕捉、屏蔽,所以也对应了下面四种情况:

  • 信号的默认处理动作是终止,进程直接终止。
  • 信号的默认处理动作是忽略,进程继续处于挂起状态。
  • 信号的默认处理动作是捕捉,进程先调用信号处理函数,然后解除挂起,执行下一步。
  • 信号的默认处理动作是屏蔽,进程继续处于挂起状态。

(2) sigsuspend 函数

sigsuspend函数的作用也是暂停当前进程直至收到信号,但 sigsuspend 还可以主动设置屏蔽哪些信号,收到这些被屏蔽的信号时,不会解除挂起

参数 mask:需要屏蔽的信号集。当前进程的屏蔽字会被替换为当前参数的屏蔽信号集,等到函数返回,会还原当前进程的屏蔽字。

  • mask == NULL:sigsuspend达到的效果和pause一样
  • mask != NULL:通过设置屏蔽信号集来主动屏蔽某些信号,收到这些被屏蔽的信号时,不会解除挂起

返回值:只会返回 -1。

2、信号驱动任务执行的两种方式

下面就以 2号信号为例,实现信号驱动任务执行。2号信号 SIGINT 可以终止前台进程,我们需要捕获2号信号,并设置相应的信号处理函数来避免当前进程被终止。

(1) sigprocmask + pause

执行任务的时候,我们不希望任务执行到一半被打断,所以在执行任务的之前我们需要调用 sigprocmask函数来屏蔽未来会收到的信号(当前场景下指的就是2号)

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handler(int signum)
{
	printf("收到并处理%d号信号\n", signum);
}

int main(){
	
	signal(2, handler);    // 捕捉2号信号
	
	sigset_t set;
	sigemptyset(&set); 		// 清空信号集
	sigaddset(&set, 2);    // 向信号集中添加2号信号

	while(1){
		sigprocmask(SIG_BLOCK, &set, NULL); 	// 屏蔽2号信号
		printf("------------------\n");
		printf("task is running\n");
		printf("------------------\n");
		sleep(1);

		sigprocmask(SIG_UNBLOCK, &set, NULL);    // 解除2号信号的屏蔽
		pause();
	}
	return 0;
}

正常情况应该是,解除2号信号的屏蔽以后,pause函数挂起的时候捕捉到了信号,此时会先去调用信号处理函数,然后解除挂起就会重新去打印“task is running” 。然而,从下面的结果可以看出,只执行了信号处理函数,但是pause函数没有解除挂起。

原因就是,由于发送信号较为频繁,在打印“task is running” 的时候收到了2号信号,但是此时2号信号被屏蔽了,解除2号信号的屏蔽以后,立马就去调用信号处理函数了,等到pause函数挂起以后,信号就已经处理完了。

因此,当信号发送较为频繁的时候,不建议使用 pause函数 来驱动任务执行

(2) sigsuspend

sigsuspend 函数被调用以后,直接进入阻塞等待的状态

  • 如果收到了屏蔽信号集中的信号,不予理会,继续挂起
  • 如果收到了屏蔽信号集以外的信号,解除挂起,并调用对应的信号处理函数 或者 执行默认处理行为。

假设 sigsuspend 函数的屏蔽信号集中包含了3号信号,那么sigsuspend收到3号信号就不会解除挂起;如果收到了2号信号,那么sigsuspend函数就会解除挂起,并调用对应的信号处理函数。

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handler(int signum)
{
	printf("收到并处理%d号信号\n", signum);
}

int main(){
	
	signal(2, handler);    // 捕捉2号信号
	
	sigset_t set;
	sigemptyset(&set); 		// 清空信号集
	sigaddset(&set, 2);    // 向信号集中添加2号信号

	sigset_t mask;        // sigsuspend的屏蔽信号集
	sigemptyset(&mask);
	sigaddset(&mask, 3);  // 向屏蔽信号集添加3号信号

	while(1){
		sigprocmask(SIG_BLOCK, &set, NULL); 	// 屏蔽2号信号
		printf("------------------\n");
		printf("task is running\n");
		printf("------------------\n");
		sleep(1);

		sigsuspend(&mask);    // 挂起状态:将进程屏蔽字替换为屏蔽信号集mask
                              // 解除挂起:恢复原本的进程屏蔽字 
	}
	return 0;
}

sigsuspend之所以不会像pause那样,是因为sigsuspend函数解除挂起以后的动作是原子的,解除挂起以后,再调用信号处理函数,保证了下一次任务的执行;pause采用的方式是先解除屏蔽,再解除挂起,这就存在一个问题,如果信号在解除挂起之前就被处理了,那么pause函数根本就收不到信号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/62440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实战:kubeadm方式搭建k8s集群(containerd)-2022.12.5(成功测试-超详细)【荐】

实战&#xff1a;kubeadm方式搭建k8s集群(containerd)-2022.12.5(成功测试-超详细)【荐】 写在开头 语雀原文阅读效果最佳&#xff0c;原文地址&#xff1a;实战&#xff1a;kubeadm方式搭建k8s集群(containerd)-2022.12.5(成功测试-超详细)【荐】 语雀 《实战&#xff1a;ku…

Liunx进程间信号

Linux进程间信号 文章目录Linux进程间信号1.信号的理解1.1 对信号的认识1.2 为什么要有信号1.3 信号概念1.4 查看系统定义的信号的方法1.5 信号的处理方式2.产生信号的方法2.1 通过终端按键发送信号2.2 通过系统函数发送信号2.3 通过软件条件发送信号2.4 通过硬件异常发送信号2…

股市资讯天宇优配|政策利好叠加竞争格局向好 机构做多建材板块

近来&#xff0c;受房地产板块上涨带动&#xff0c;建材板块也敞开一轮反弹行情&#xff0c;东方雨虹、三棵树、科顺股份等体现抢眼。在组织看来&#xff0c;房地产职业近期利好政策频出&#xff0c;商场对建材职业后期需求的忧虑将会消解。另一方面&#xff0c;在过去一年多的…

计算机总线详解(数据总线、地址总线、控制总线)

文章目录1 概述2 总线分类2.1 数据总线 Data Bus2.2 地址总线 Address Bus2.3 控制总线 Control Bus3 扩展3.1 常考题3.2 百度百科 - 总线 Bus1 概述 总线&#xff08;Bus&#xff09;是计算机各种功能部件之间传送信息的 公共通信干线如果说 主板&#xff08;Mother Board&am…

Hadoop集群安装和搭建

Hadoop集群安装和搭建 前言    Hadoop是一个开源的、可运行与Linux集群上的分布式计算平台&#xff0c;用户可借助Hadoop存有基础环境的配置&#xff08;虚拟机安装、Linux安装等&#xff09;&#xff0c;Hadoop集群搭建&#xff0c;配置和测试。 一、虚拟机的安装  VMware …

.sqlite后缀文件转为sql文件

第一步 安装sqlite3 1.官网下载 https://www.sqlite.org/download.html &#xff0c;因为我是win64的&#xff0c;需要下载图片这两个安装包 2.将解压下载的安装包 首先创建一个文件夹&#xff0c;比如放在D盘&#xff0c;在D盘创建一个文件目录sqlite,路径最终为D:\sqlit…

二本蒟蒻的带牌退役感言(感谢两年来的acm经历)

TP20年10月20年 - 21年期间22年开始&#xff0c;大二下暑假后&#xff0c;怎么就大三了&#xff0c;时间好快第47届icpc杭州站润~20年10月 一个高考发挥失常的蒟蒻来到了化大。他带着不甘和兴奋走进了大学的殿堂&#xff0c;励志要好好学习天天向上。 可是很快现实就给予了充…

Eolink如何解决API测试痛点

文章目录前言一、API测试的痛点二、eolink可以解决什么&#xff1f;2.1 Eolink是什么&#xff1f;2.2 Eolink可以解决什么&#xff1f;三、环境安装以及实践操作3. 1 下载安装3.2 创建项目四、支持所有自动化接口测试场景4.1 单API接口测试4.2 API变更智能通知4.3 API历史版本对…

Kube-OVN子网

子网是 Kube-OVN 中的一个核心概念和基本使用单元&#xff0c;Kube-OVN 会以子网来组织 IP 和网络配置&#xff0c;每个 Namespace 可以归属于特定的子网&#xff0c; Namespace 下的 Pod 会自动从所属的子网中获取 IP 并共享子网的网络配置&#xff08;CIDR&#xff0c;网关类…

代码随想录刷题Day55 | 392. 判断子序列 | 115. 不同的子序列

代码随想录刷题Day55 | 392. 判断子序列 | 115. 不同的子序列 392. 判断子序列 题目&#xff1a; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形…

阿里又出神作:最新Spring Cloud Alibaba全解手册限时开源,手慢无

有一说一&#xff0c;网上的那些Spring Cloud 学习资料大多是老版本那套东西&#xff0c;学习 Spring Cloud Alibaba 才是目前最正确的姿势&#xff01;Spring Cloud Alibaba 基于 Spring Cloud 构建&#xff0c;提供了对 Alibaba 组件的封装而已&#xff0c;其最顶层的抽象还是…

牛客Top101 JS合并两个排序的列表

描述 输入两个递增的链表&#xff0c;单个链表的长度为n&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 数据范围&#xff1a; 0 ≤n≤1000&#xff0c;-1000≤节点值≤1000 要求&#xff1a;空间复杂度 O(1)&#xff0c;时间复杂度 O(n) 如输入{1,3,5},{…

[附源码]计算机毕业设计基于Springboot设备运维平台出入库模块APP

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

java面试强基(17)

ArrayList 与 LinkedList 区别? 是否保证线程安全&#xff1a; ArrayList 和 LinkedList 都是不同步的&#xff0c;也就是不保证线程安全&#xff1b;底层数据结构&#xff1a; ArrayList 底层使用的是 Object 数组&#xff1b;LinkedList 底层使用的是 双向链表 数据结构&a…

Vue(第十七课)AXIOS对JSON数据的增删改查

Vue(第十七课)AXIOS对JSON数据的IDUS Vue(第十六课)JSON-SERVE和POSTMAN技术中对数据的增删改查_星辰镜的博客-CSDN博客 get:获取数据,请求指定的信息,返回实体对象post:向指定资源提交数据(例如表单提交或文件上传)put:更新数据,从客户端向服务器传送的数据取代指定的…

Elasticsearch中的语言分析器-IK分词器

IK分词器是一个中文语言的语言分析器,以下为指定使用“IK分词器”的案例: 在Postman中,向ES服务器发送GET请求: http://192.168.1.108:9200/_analyze 请求体里面的内容为(在请求体里指定要分析的文本): {"text":"测试单词" } 调用上述接口后,其…

(附源码)SSM 汽车停车位共享APP 毕业设计 041534

汽车停车位共享APP 摘 要 随着社会经济的快速发展,我国机动车保有量大幅增加,城市交通问题日益严重。为缓解用户停车难问题,本文设计并实现了APP停车位共享系统.该系统通过错峰停车达到车位利用率最大化.基于现状分析,本文结合实际停车问题,从系统应用流程,系统软硬件设计和系统…

Flink

文章目录1. 概述1.1 Apache Flink1.2 特点1.3 Flink VS Spark Streaming2. 安装与部署2. Flink运行时的组件2.1 作业管理器(JobManager)2.2 任务管理器(TaskManager)2.3 资源管理器(ResourceManager)2.4 分发器&#xff08;Dispatcher)3. 任务提交流程4. Flink API4.1 不用级别…

[附源码]JAVA毕业设计旅游景点展示平台的设计与实现(系统+LW)

[附源码]JAVA毕业设计旅游景点展示平台的设计与实现&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09…

【cocos源码学习】模板示例工程的目录说明

环境说明 硬件&#xff1a;macbook pro 四核Intel Core i7系统&#xff1a;macOS Big Sur 11.4.2、 xcode Version 13.1 、cmake 3.20.5软件&#xff1a;iterm2 Build 3.4.8、zsh 5.8、Android Studio Dolphin | 2021.3.1cocos2d-x v4 &#xff1a; 官方下载压缩包 http://coc…