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

    • 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信号简介
    • 发送和捕获信号
      • 信号处理函数
      • signal函数举例
        • 响应控制台信号
      • 发送信号
        • 示例代码
        • 输出
        • 分析
    • 更健壮的信号接口
    • 信号集处理
  • 进程间通信

  • Socket

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

发送和捕获信号

# 发送和捕获信号

发送信号:进程可以使用系统调用kill()向另一个进程或者进程组发送信号。 捕获信号:进程可以使用系统调用signal()或者sigaction()来安装信号处理函数来捕获特定的信号,本篇文章主要介绍signal()。

# 信号处理函数

程序可以用signal库函数来处理信号:

#include <signal.h>
void (*signal( int sig, void (*func)(int)))(int);
1
2
  • signal是一个带有sig和func两个参数的函数,准备捕获或忽略的信号由参数sig给出,接收到指定的信号后将要调用的函数由func给出。

  • 信号处理函数必须有一个int类型参数(即接收到的信号代码),并且返回值为void*。

  • signal函数本身也返回一个同类型的函数(指针),即先前用来处理这个信号的函数。

  • func取值也可为下列两个宏:

    • SIG_IGN:忽略信号

    • SIG_DFL:恢复默认行为

# signal函数举例

# 响应控制台信号

#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()
{
	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
  • 编写程序,它将响应用户敲入的组合键ctrl+c,在屏幕上打印出一条适当的消息,而不是终止程序,当用户第二次按下此组合键时,终止程序。

# 发送信号

  • 进程可以通过调用kill函数向包括它本身在内的其他进程发送一个信号。
  • 要想发送一个信号,发送进程必须拥有相应的权限,通常两个进程必须拥有相同的用户ID,进程只能发送信号给属于同一个用户的其他进程。
  • kill调用失败可能的原因:
    • 给定的信号无效
    • 发送进程权限不够
    • 目标进程不存在。

# 示例代码

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static int alarm_fired = 0;

void ding(int sig)
{
	alarm_fired = 1;
}

int main()
{
	int pid;
	printf("alarm application starting\n");
	if((pid = fork()) == 0) 
	{
		sleep(5);
		kill(getppid(), SIGALRM);
		exit(0);
	}
	printf("waiting for alarm to go off\n");
	signal(SIGALRM, ding);
    //suspend until a signal is received 
	//pause() shall return after the signal-catching function returns.
	pause();
	if (alarm_fired)
		printf("Signal is received!\n");
	printf("done\n");
	exit(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
27
28
29
30
31

# 输出

alarm application starting
waiting for alarm to go off
Signal is received!
done
1
2
3
4

# 分析

这段代码是一个使用pause()函数等待信号的程序。程序会创建一个子进程,在5秒后向父进程发送SIGALRM信号,父进程等待信号并在收到信号后输出一条信息。

编辑 (opens new window)
#C#Single#Linux#信号
上次更新: 2023/02/19, 10:48:02
Linux信号简介
更健壮的信号接口

← Linux信号简介 更健壮的信号接口→

最近更新
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
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式