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

    • 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信号简介
    • 发送和捕获信号
    • 更健壮的信号接口
    • 信号集处理
      • 信号集处理函数
      • 进程信号屏蔽字处理函数
      • 信号集处理例子
        • 示例代码
        • 输出
        • 分析
  • 进程间通信

  • Socket

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

信号集处理

# 信号集处理

信号集处理可以用于阻塞、接收和处理信号。通过信号集,我们可以在进程或线程中选择性地阻塞或接收特定的信号,从而对系统中的事件进行响应和处理。

# 信号集处理函数

signal.h文件中声明了处理信号集的若干函数。

//向信号集中增加新的信号
int sigaddset(sigset_t* set, int signo);
//将信号集初始化为空
int sigemptyset(sigset_t* set);
//将信号集初始化为包括所有信号
int sigfillset(sigset_t* set);
//从信号集中删掉给定的信号
int sigdelset(sigset_t* set , int signo);
1
2
3
4
5
6
7
8

# 进程信号屏蔽字处理函数

signal.h中声明了处理进程信号屏蔽字的函数。

int sigprocmask(int how, const sigset_t* set,sigset_t* oset);
1
  • how:

    • SIG_BLOCK:把参数set中的信号添加到信号屏蔽字中。
    • SIG_SETMASK:把信号屏蔽字设置为参数set中的信号。
    • SIG_UNBLOCK:从信号屏蔽字中删除参数set中的信号。
  • set:要添加信号的信号集屏蔽字

  • oset:返回旧的信号集屏蔽字

# 信号集处理例子

# 示例代码

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

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

int main()
{
	sigset_t* set;
	sigset_t* oldset;
	sigemptyset(set);
	sigaddset(set, SIGINT);	//	ctrl c
	sigprocmask(SIG_BLOCK, set, oldset);

	signal(SIGINT, sig_alarm);
	while(1) 
	{
		printf("waiting here!\n");
		sleep(1);
	}
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 输出

waiting here!
waiting here!
waiting here!
^Cwaiting here!
waiting here!
^Cwaiting here!
^C^Cwaiting here!
^Cwaiting here!
^Cwaiting here!
waiting here!
1
2
3
4
5
6
7
8
9
10

没法停止程序,最终使用ps -aux查找进程号kill -9 pid杀掉进程。

# 分析

在这段代码中,使用了sigset_t类型的指针变量set和oldset,并使用sigemptyset()函数将信号集初始化为空集,再使用sigaddset()函数将SIGINT信号添加到信号集中。然后使用sigprocmask()函数将当前进程的信号屏蔽字设置为set,从而阻塞了SIGINT信号。

接着,使用signal()函数为SIGINT信号注册信号处理函数sig_alarm。在sig_alarm信号处理函数中,输出捕获的信号,并调用signal()函数将SIGINT信号的处理方式设置为默认处理方式,但是这是无效的,因为在sigprocmask(SIG_BLOCK, set, oldset);中传入了SIG_BLOCK。

在主循环中,进程会不断输出waiting here!并休眠1秒钟,直到收到SIGINT信号。由于在进程中使用了sigprocmask()函数屏蔽了SIGINT信号,因此SIGINT信号被阻塞,不会被立即处理。

编辑 (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
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式