当前位置: 首页 > news >正文

Linux信号sigaction / signal

Linux信号sigaction / signal

文章目录

  • Linux信号sigaction / signal
    • 目的
    • 函数原型
    • struct sigaction
    • 信号枚举值
      • ISO C99 signals.
      • Historical signals specified by POSIX.
      • New(er) POSIX signals (1003.1-2008, 1003.1-2013).
      • Nonstandard signals found in all modern POSIX systems(including both BSD and Linux).
    • 测试
      • 1 处理信号后重启系统调用
      • 2 处理信号后不重启系统调用
      • 3 使用 sigaction 函数为 SIGUSR1 和 SIGUSR2 信号注册处理函数
    • 实际代码框架
      • 1. signal
      • 2 将程序放入线程中
    • 终端间通过kill发送信号
    • Reference

目的

我们可以通过sigaction函数或者signal指定某种特定信号,在程序执行过程中,通过发送信号,达到改变程序运行状态的目的,比如让程序停止等。

函数原型

获取或者设定与指定信号相关联的处理动作。

/* Get and/or set the action for signal SIG.  */
extern int sigaction (int __sig, const struct sigaction *__restrict __act,struct sigaction *__restrict __oact) __THROW;extern __sighandler_t signal (int __sig, __sighandler_t __handler)__THROW;

sigaction函数执行信号处理程序时,会把当前信号加入到进程的信号屏蔽字中,从而防止在进行信号处理期间信号丢失。

程序接收信号示意图

对signal(),Linux默认会自动重启动被中断的系统调用;

而对于 sigaction(),Linux默认并不会自动重启动,所以如果希望执行信号处理后自动重启动先前中断的系统调用,就需要为sa_flags指定 SA_RESTART标志

struct sigaction

当信号到达时,用于描述采取的动作的结构

/* Structure describing the action to be taken when a signal arrives.  */
struct sigaction{/* Signal handler.  */
#if defined __USE_POSIX199309 || defined __USE_XOPEN_EXTENDEDunion{/* Used if SA_SIGINFO is not set.  */__sighandler_t sa_handler;/* Used if SA_SIGINFO is set.  */void (*sa_sigaction) (int, siginfo_t *, void *);}__sigaction_handler;
# define sa_handler	__sigaction_handler.sa_handler
# define sa_sigaction	__sigaction_handler.sa_sigaction
#else__sighandler_t sa_handler;
#endif/* Additional set of signals to be blocked.  */__sigset_t sa_mask;/* Special flags.  */int sa_flags;/* Restore handler.  */void (*sa_restorer) (void);};
  • sa_handler 和signal()的参数__handler相同,代表新的信号处理函数
  • sa_mask 表示处理信号时,需要阻止的信号集
  • sa_flags 处理信号时的标志位
    • SA_RESETHAND:在调用处理函数前,将信号的处理函数重置为缺省值(即SIG_IGN)
    • SA_RESTART:执行信号处理后,自动重启先前中断的系统调用
    • SA_NODEFER :一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号
    • SA_ONSTACK:使用由sigaltstack()安装的备选栈
    • SA_SIGINFO:调用信号处理程序时携带了额外参数(提供了关于信号的深入信息)

信号枚举值

ISO C99 signals.

符号数值含义
SIGINT2Interactive attention signal.
SIGILL4Illegal instruction.
SIGABRT6Abnormal termination.
SIGFPE8Erroneous arithmetic operation.
SIGSEGV11Invalid access to storage.
SIGTERM15Termination request.

Historical signals specified by POSIX.

符号数值含义
SIGHUP1Hangup.
SIGQUIT3Quit.
SIGTRAP5Trace/breakpoint trap.
SIGKILL9Killed.
SIGBUS10Bus error.
SIGSYS12Bad system call.
SIGPIPE13Broken pipe.
SIGALRM14Alarm clock.

New(er) POSIX signals (1003.1-2008, 1003.1-2013).

符号数值含义
SIGURG16Urgent data is available at a socket.
SIGSTOP17Stop, unblockable.
SIGTSTP18Keyboard stop.
SIGCONT19Continue.
SIGCHLD20Child terminated or stopped.
SIGTTIN21Background read from control terminal.
SIGTTOU22Background write to control terminal.
SIGPOLL23Pollable event occurred (System V).
SIGXCPU24CPU time limit exceeded.
SIGXFSZ25File size limit exceeded.
SIGVTALRM26Virtual timer expired.
SIGPROF27Profiling timer expired.
SIGUSR130User-defined signal 1.
SIGUSR231User-defined signal 2.

Nonstandard signals found in all modern POSIX systems(including both BSD and Linux).

符号数值含义
SIGWINCH28Window size change (4.3 BSD, Sun).

测试

1 处理信号后重启系统调用

#include <iostream>
#include "stdio.h"
#include <signal.h>
#include <stdlib.h>void signalHandle(int signum) {if(signum  = SIGINT) {std::cout << "SIGINT recived" << std::endl;}
}int main(void){struct sigaction act;sigemptyset(&act.sa_mask);//这里使用SA_RESTART执行信号处理后自动重启到先前中断的系统调用,可以多次捕捉信号act.sa_flags = (SA_SIGINFO|SA_RESTART);act.sa_handler = signalHandle;sigaction(SIGINT, &act, NULL);while(1){}
}

当按下 CTRL + c时,会一直打印。

$ ./main 
^CSIGINT recived
^CSIGINT recived
^CSIGINT recived

2 处理信号后不重启系统调用

#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>void show_handler(int sig)
{printf("I got signal %dn\n", sig);int i;for(i = 0; i < 5; i++) {printf("i = %dn\n", i);sleep(1);}
}int main(void)
{// section 1int i = 0;struct sigaction act, oldact;act.sa_handler = show_handler;sigaddset(&act.sa_mask, SIGQUIT);         act.sa_flags = SA_RESETHAND | SA_NODEFER; //act.sa_flags = 0;                       sigaction(SIGINT, &act, &oldact);while(1) {sleep(1);printf("sleeping %dn\n", i);i++;}return 0;
}

程序起来后,控制台输入CTRL + c,能够接收到信号。再次输入时,程序退出。

(base) qiancj@qiancj-Dell-G15-5510:~/codes/test/build$ ./main 
sleeping 0
sleeping 1
^CI got signal 2
i = 0
i = 1
i = 2
i = 3
i = 4
sleeping 2
^C
(base) qiancj@qiancj-Dell-G15-5510:~/codes/test/build$ 

3 使用 sigaction 函数为 SIGUSR1 和 SIGUSR2 信号注册处理函数

#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>static void sig_usr(int signum)
{if(signum == SIGUSR1){printf("SIGUSR1 received\n");}else if(signum == SIGUSR2){printf("SIGUSR2 received\n");}else{printf("signal %d received\n", signum);}
}int main(void)
{
// section 2char buf[512];int  n;struct sigaction sa_usr;sa_usr.sa_flags = 0;sa_usr.sa_handler = sig_usr;   //信号处理函数sigaction(SIGUSR1, &sa_usr, NULL);sigaction(SIGUSR2, &sa_usr, NULL);printf("My PID is %dn\n", getpid());while(1){if((n = read(STDIN_FILENO, buf, 511)) == -1){if(errno == EINTR){printf("read is interrupted by signal\n");}}else{buf[n] = '0';printf("%d bytes read: %s\n", n, buf);}}return 0;
}

当一个终端启动程序,获取当前PID号(13770),另一个终端输入kill -USR1 32230或者kill -USR2 32230,第一个终端就会收到中断信号

(base) qiancj@qiancj-Dell-G15-5510:~/codes/test/build$ ./main
My PID is 32230nSIGUSR1 received
read is interrupted by signal
SIGUSR2 received
read is interrupted by signal

实际代码框架

当程序需要一直运行时,需要人为中断停止时,可以使用信号函数,具体框架可以设置为以下2种:

1. signal

#include <csignal>
#include <iostream>
#include <sstream>
#include <string>
#include <thread>sig_atomic_t stop_flag = 0;void INTSigHandler(int32_t num) {stop_flag = 1;std::cout << "  Signal Interactive attention " << num << " received."<< std::endl;
}int main(int argc, char **argv) {signal(SIGINT, INTSigHandler);// work always.......while ((!stop_flag)) {LOG_INFO << "I am working...";std::this_thread::sleep_for(std::chrono::seconds(1));}// Stop working! Go to rest!return 0;
}

2 将程序放入线程中

#include <chrono>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>namespace {std::atomic_bool continueExecution{true};void SigTermHandler(int signal) {if (signal == SIGTERM || signal == SIGINT) {// set atomic exit flagcontinueExecution = false;}
}bool RegisterSigTermHandler() {struct sigaction sa;sa.sa_handler = SigTermHandler;sa.sa_flags = 0;sigemptyset(&sa.sa_mask);// register signal handlerif (sigaction(SIGTERM, &sa, NULL) == -1) {// Could not register a SIGTERM signal handlerreturn false;}if (sigaction(SIGINT, &sa, NULL) == -1) {// Could not register a SIGTERM signal handlerreturn false;}return true;
}}  // namespacevoid ThreadAct1();void ThreadAct1() {while (continueExecution) {// always work......// sleepstd::this_thread::sleep_for(std::chrono::milliseconds(10000));}
}int main(int argc, char *argv[]) {if (!RegisterSigTermHandler()) {std::cout << "Unable to register signal handler" << std::endl;}// start threadstd::thread act1(ThreadAct1);act1.join();return 0;
}

终端间通过kill发送信号

(base) qiancj@qiancj-Dell-G15-5510:~$ kill --help
kill: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]Send a signal to a job.Send the processes identified by PID or JOBSPEC the signal named bySIGSPEC or SIGNUM.  If neither SIGSPEC nor SIGNUM is present, thenSIGTERM is assumed.Options:-s sig	SIG is a signal name-n sig	SIG is a signal number-l	list the signal names; if arguments follow `-l' they areassumed to be signal numbers for which names should be listed-L	synonym for -lKill is a shell builtin for two reasons: it allows job IDs to be usedinstead of process IDs, and allows processes to be killed if the limiton processes that you can create is reached.Exit Status:Returns success unless an invalid option is given or an error occurs.

信号种类

(base) qiancj@qiancj-Dell-G15-5510:~$ kill -l1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

Reference

  • linux中sigaction函数详解
  • sigaction详细解析

相关文章:

Linux信号sigaction / signal

Linux信号sigaction / signal 文章目录Linux信号sigaction / signal目的函数原型struct sigaction信号枚举值ISO C99 signals.Historical signals specified by POSIX.New(er) POSIX signals (1003.1-2008, 1003.1-2013).Nonstandard signals found in all modern POSIX system…...

坦克大战第一阶段代码

package tanke.game;import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Vector;//为了监听键盘事件&#xff0c;实现keylistener public class mypanel extends JPanel implements KeyListener …...

博客系统前端实现

目录 1.预期效果 2.实现博客列表页 3.实现博客正文页 4.实现博客登录页 5.实现博客编辑页面 1.预期效果 对前端html,css,js有大致的了解后,现在我们实现了一个博客系统的前端页面.一共分为四个页面没分别是:登陆页面,博客列表页,博客正文页,博客编辑页 我们看下四个界面…...

ChatGPT技术原理、研究框架,应用实践及发展趋势(附166份报告)

​ 一、AI框架重要性日益突显&#xff0c;框架技术发展进入繁荣期&#xff0c;国内AI框架技术加速发展&#xff1a; 1、AI框架作为衔接数据和模型的重要桥梁&#xff0c;发展进入繁荣期&#xff0c;国内外框架功能及性能加速迭代&#xff1b; 2、Pytorch、Tensorflow占据AI框…...

【屏幕自适应页面适配问题】CSS的@media,为了适应1440×900的屏幕,使用@media解决问题

文章目录bug修改实例CSS3 media 查询CSS 多媒体查询&#xff0c;适配各种设备尺寸bug修改实例 <template><div id"deptAllDown" style"height: 400px;width:880px"/> </template>为了适应1440900的屏幕&#xff0c;使用media解决问题 …...

一篇文章理解堆栈溢出

一篇文章理解堆栈溢出引言栈溢出ret2text答案ret2shellcode答案ret2syscall答案栈迁移答案堆溢出 unlink - UAF堆结构小提示向前合并/向后合并堆溢出题答案引言 让新手快速理解堆栈溢出&#xff0c;尽可能写的简单一些。 栈溢出 代码执行到进入函数之前都会记录返回地址到SP…...

优化模型验证关键代码27:多旅行商问题的变体-多起点单目的地问题和多汉密尔顿路径问题

目录 1 多起点单目的地问题(Multiple departures single destination mTSP) 1.1 符号列表 1.2 数学模型 1.4 解的可视化结果...

快速搭建第一个SpringCloud程序

目录 1、Spring Boot项目脚手架快速搭建 1.1 生成工程基本配置 1.2 生成工程。 1.3 导入开发工具&#xff08;此处为Idea&#xff09; 1.4 运行代码 1.5 验证是否能访问 2、Spring Cloud环境搭建 2.1 版本匹配问题 2.2 Spring Cloud环境测试 3、引入Eureka Server 3…...

【离散数学】图论

1、有n个点没有边 零图 2、有1个点没有边 平凡图 3、含有平行边的图 多重图 4、简单图 不含有平行边和自回环的图 5、任意两个结点之间都有边 完全图 6、环贡献 两度 7、所有顶点的度数之和等于边数的两倍 8、在有向图中所有顶点的出度之和 或者 入度之和 等于边数 9、度数为…...

代码随想录算法训练营第三十七天-贪心算法6| 738.单调递增的数字 968.监控二叉树 总结

738.单调递增的数字 贪心算法 题目要求小于等于N的最大单调递增的整数&#xff0c;那么拿一个两位的数字来举例。 例如&#xff1a;98&#xff0c;一旦出现strNum[i - 1] > strNum[i]的情况&#xff08;非单调递增&#xff09;&#xff0c;首先想让strNum[i - 1]--&#…...

【Linux】线程中的互斥锁、条件变量、信号量(数据安全问题、生产消费模型、阻塞队列和环形队列的实现)

文章目录1、线程互斥1.1 线程间频繁切换导致的问题1.2 使用互斥锁1.3 互斥锁的原理1.4 线程中的数据安全问题2、线程同步之条件变量2.1 生产消费模型2.2 条件变量概念和调用函数2.3 阻塞队列的实现3、线程同步之信号量3.1 理解信号量3.2 信号量接口3.3 环形队列的实现4、小结1、…...

MySQL8.0的安装和配置

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…...

LinuxGUI自动化测试框架搭建(三)-虚拟机安装(Hyper-V或者VMWare)

&#xff08;三&#xff09;-虚拟机安装&#xff08;Hyper-V或者VMWare&#xff09;1 Hyper-V安装1.1 方法一&#xff1a;直接启用1.2 方法二&#xff1a;下载安装1.3 打开Hyper-V2 VMWare安装注意&#xff1a;Hyper-V或者VMWare只安装一个&#xff0c;只安装一个&#xff0c;只…...

改进YOLO系列:数据增强扩充(有增强图像和标注),包含copypaste、翻转、cutout等八种增强方式

这里写目录标题 一、简介二、数据增强方法介绍复制-粘贴(Copy-paste)翻转(Flip)Cutout加噪声(Noise)亮度调整(Brightness)平移(Shift)旋转(Rotation)裁剪(Crop)copy-paste的代码一、简介 数据增强是一种通过对原始数据进行随机变换、扰动等操作来生成新的训练样…...

c++11 标准模板(STL)(std::stack)(一)

定义于头文件 <stack> template< class T, class Container std::deque<T> > class stack;std::stack 类是容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO &#xff08;先进后出&#xff09;数据结构。 该类模板表现为底层容器的包装…...

C++-c语言词法分析器

一、运行截图 对于 Test.c 的词法分析结果 对于词法分析器本身的源代码的分析结果 二、主要功能 经过不断的修正和测试代码&#xff0c;分析测试结果&#xff0c;该词法分析器主要实现了以下功能&#xff1a; 1. 识别关键字 实验要求&#xff1a;if else while do for main…...

Maven工具复习

Maven从入门到放弃Maven概述Maven 的配置Maven的基本使用IDEA 配置MAVENMaven坐标IDEA 创建MavenIDEA 导入Maven关于右侧Maven小标签(也就是Maven面板)找不到问题的解决办法关于不小心把IDEA主菜单搞消失的解决办法依赖管理Maven概述 Maven是一个工具提供了一套标准的项目结构…...

算法总结-深度优先遍历和广度优先遍历

深度优先遍历(Depth First Search&#xff0c;简称DFS) 与广度优先遍历(Breath First Search&#xff0c;简称BFS)是图论中两种非常重要的算法&#xff0c;生产上广泛用于拓扑排序&#xff0c;寻路(走迷宫)&#xff0c;搜索引擎&#xff0c;爬虫等。 一、深度优先遍历 深度优先…...

【Linux】Centos安装mvn命令(maven)

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录一、下载maven包方法一&#xff1a;官…...

驱动保护 -- 通过PID保护指定进程

一、设计界面 1、添加一个编辑框输入要保护的进程PID&#xff0c;并添加两个按钮&#xff0c;一个保护进程&#xff0c;一个解除保护 2、右击编辑框&#xff0c;添加变量 二、驱动层代码实现 1、声明一个受保护的进程PID数组 static UINT32 受保护的进程PID[256] { 0 }; 2…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...