长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 文件操作

  • Linux进程和线程

  • Linux信号

    • Linux信号简介
    • 发送和捕获信号
    • 更健壮的信号接口
      • 更健壮的信号接口
        • struct sigaction结构
      • 使用sigaction重写代码
        • 示例代码
        • 输出
        • 分析
      • sigaction函数的优点
    • 信号集处理
  • 进程间通信

  • Socket

  • C语言
  • Linux信号
DC Wang
2023-02-19
目录

更健壮的信号接口

# 更健壮的信号接口

进程可以使用系统调用signal()或者sigaction()来安装信号处理函数来捕获特定的信号,sigaction()是一个更健壮的信号接口。

# 更健壮的信号接口

UNIX规范提供了一个更加健壮的信号编程接口:sigaction,声明如下:

#include <signal.h>
int sigaction(int sig, const struct sigaction* act, struct sigaction* oact);
1
2
  • sig:接收到的信号
  • act:新结构体变量,指定接收到信号后的动作
  • oact:旧结构体变量,由sigaction函数返回

# struct sigaction结构

  • void (* sa_handler)(int):与sig信号相连的动作,当收到sig信号后执行此函数。该参数可以被设置为SIG_DFL,或者SIG_IGN。
  • sigset_t sa_mask:该字段指定了一个信号集,该信号集将被加入到进程的信号屏蔽字当中,这是一组将被阻塞且不会传递给该进程的信号。
  • int sa_flags:信号函数选项标识。如果希望信号处理重置为默认处理方式,可将其设置为RESETHAND,如果希望设置为上一次设置的处理方式,可设置为RESTART。

# 使用sigaction重写代码 (opens new window)

# 示例代码

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

void sig_alarm(int sig)
{
	printf("---the signal received is %d. \n", sig);
}

int main()
{
	struct sigaction act;
	act.sa_handler = sig_alarm;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_RESETHAND;
	sigaction(SIGINT, &act, 0);
	while(1) 
	{
		printf("waiting here!\n");
		sleep(1);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 输出

waiting here!
waiting here!
waiting here!
^C---the signal received is 2.
waiting here!
waiting here!
waiting here!
^C
1
2
3
4
5
6
7
8

# 分析

这段代码使用了struct sigaction结构体来注册SIGINT信号的处理函数,指定的处理函数是sig_alarm。同时,使用了sigemptyset()函数将信号集初始化为空集,这样在信号处理函数执行时不会阻塞任何其他信号。sa_flags成员设置了SA_RESETHAND标志,这意味着在处理完信号后,将信号处理函数重置为默认处理方式。

在主循环中,进程会不断输出waiting here!并休眠1秒钟,直到收到SIGINT信号。当信号被捕获后,程序会执行sig_alarm函数,并输出被捕获的信号值,然后SA_RESETHAND标志将会使得该信号的处理函数被重置为默认处理方式,这将导致下一次信号到来时使用系统默认的处理方式而不是之前设置的处理函数。接着,主循环会继续执行,等待下一个信号的到来。

# sigaction函数的优点

sigaction相对于signal函数的优点主要有以下几点:

  1. 更加灵活:sigaction可以对信号的处理进行更加精细的控制,可以指定信号处理函数的地址、控制信号的信号集、设置处理信号的选项等。相比之下,signal函数仅能指定信号处理函数的地址。
  2. 可重入性:sigaction在设置信号处理函数时可以使用SA_RESTART选项来保证系统调用在收到信号后能够自动恢复,避免了可能的竞争条件,从而保证了程序的可重入性。

一般来说,在编写需要对信号进行处理的程序时,建议使用sigaction函数而不是signal函数。

编辑 (opens new window)
#C#Single#Linux#信号
上次更新: 2023/02/19, 10:48:02
发送和捕获信号
信号集处理

← 发送和捕获信号 信号集处理→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式