Linux系统编程(信号处理机制)

简介: Linux系统编程(信号处理机制)

前言

本篇文章我们来讲解信号的处理机制,信号处理在Linux操作系统中必不可少,这一点值得大家注意,信号又会与中断,异常一起讨论,那么下面我们就来看看到底什么是信号吧。

一、中断,异常,信号的区别

中断、异常和信号是计算机系统中的三个相关但不完全相同的概念。它们在发生的时机、触发方式和处理机制上有所不同。

中断(Interrupt):

1.中断是由硬件发出的一种信号,用于打断处理器当前的执行流程,以响应特定的硬件事件或请求。

2.中断可以来自外部设备(例如键盘、鼠标、硬盘控制器)或系统内部(例如定时器、异常或错误)。

3.当发生中断时,处理器会暂停当前的执行并切换到中断处理程序来处理中断事件,然后在处理完中断后回到原来的执行上下文

异常(Exception):

1.异常是在程序执行期间发生的事件或错误条件,可能导致程序的正常流程中断。

2.异常可以是由硬件错误(例如除零错误、无效的内存访问)或软件错误(例如逻辑错误、非法操作)触发的错误情况。

3.异常通常是同步的,也就是说,它们在执行特定的指令时发生,并由程序自身或相关硬件直接处理。

4.异常的处理方式通常由编程语言、操作系统或硬件定义,可以通过异常处理机制(例如 try-catch 块)捕获和处理。

信号(Signal):

1.信号是一种在软件层面上由操作系统或进程间通信机制发送的异步通知。

2.信号可以用于通知进程发生的特定事件,如用户操作(例如按下 Ctrl+C),操作系统事件(例如进程终止),或由其他进程发送的消息。

3.信号是在进程执行期间以异步方式发出的,可以打断当前的执行流程。

4.信号通常用于处理外部事件或异常情况,例如捕获异常,终止进程或重新启动进程等。

总结:

1.中断是由硬件发出的打断处理器当前执行流程的信号,用于响应硬件事件。

2.异常是在程序执行期间发生的事件或错误条件,用于响应特定的错误情况。

3.信号是在软件层面上由操作系统或进程间通信机制发送的异步通知,用于处理外部事件或异常情况。

它们在触发方式、处理机制和使用场景上有所不同,但都可以用于在计算机系统中处理特定的事件、错误和异常情况。

二、信号在Linux中的标识

每个信号都由一个唯一的数字标识符来表示,这些数字被称为信号编号。

信号编号是整数值,通常用正整数来表示,例如SIGINT、SIGTERM等。这些信号编号定义在系统头文件 <signal.h> 中,并在C语言中使用 SIG 前缀。

以下是一些常见的信号编号及其含义:

SIGHUP (1): 终端挂起或控制进程终止。

SIGINT (2): 使用键盘输入的中断信号。

SIGQUIT (3): 使用键盘输入的退出信号。

SIGILL (4): 非法指令。

SIGABRT (6): 异常终止。

SIGFPE (8): 浮点异常。

SIGKILL (9): 强制进程终止。

SIGALRM (14): 闹钟超时。

SIGTERM (15): 终止请求。

三、信号处理相关函数

signal()

函数原型:

void (*signal(int signum, void (*handler)(int)))(int)

功能:signal() 函数用于注册信号处理函数,指定在接收到特定信号时要执行的操作。

参数:

signum:要捕获和处理的信号编号。

handler:指向信号处理函数的指针,可以是自定义函数或内置的信号处理函数。

返回值:返回一个函数指针,指向以前注册的信号处理函数。

raise()

函数原型:

int raise(int sig)

功能:raise() 函数用于在当前进程内部生成信号。它向当前进程发送指定的信号。

参数:

sig:要发送的信号编号。

返回值:成功时返回0,否则返回一个非零值。

kill()

函数原型:

int kill(pid_t pid, int sig)

功能:kill() 函数用于向指定进程或进程组发送信号。

参数:

pid:要发送信号的进程的进程ID(PID)。可以是正整数值,表示单个进程的PID,也可以是负整数值,表示进程组的PID(将信号发送给该进程组中的所有进程)。

sig:要发送的信号编号。

返回值:成功时返回0,否则返回一个非零值。

这些函数可以一起使用来进行信号的处理。首先,使用 signal() 函数注册信号处理函数,指定接收到特定信号时要执行的操作。然后,可以使用 raise() 函数在当前进程中生成信号,或使用 kill() 函数向其他进程发送信号。

需要注意的是,不同的信号有不同的含义和用途。要正确使用信号处理函数和相关函数,需要了解不同的信号及其处理方式。可以通过查阅相关文档或系统头文件 <signal.h> 了解所有可用的信号及其意义。

四、代码实验

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void signal_handle(int sig)
{
    printf("sig = %d\n", sig);
}
int main(void)
{
    signal(SIGINT, signal_handle);
    while(1)
    {
        sleep(1);
    }
    return 0;
}

执行效果:

按下ctrl加c后被信号处理函数捕捉到了,并且打印了信号的数值。

下面的代码演示了怎么样使用信号进行线程之间通信。

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void signal_handle(int sig)
{
    printf("sig = %d\n", sig);
}
int main(void)
{
    signal(40, signal_handle);
    while(1)
    {
        sleep(1);
    }
    return 0;
}
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
    pid_t pid = atoi(argv[1]);
    kill(pid, 40);
    raise(SIGINT);
    while(1)
    {
        sleep(1);
    }
    return 0;
}

总结

本篇文章就讲解到这里,大家看完后可以好好实验一下。


相关文章
|
9天前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
126 78
|
13天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
48 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
9天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
61 13
|
10天前
|
Ubuntu Linux C++
Win10系统上直接使用linux子系统教程(仅需五步!超简单,快速上手)
本文介绍了如何在Windows 10上安装并使用Linux子系统。首先,通过应用商店安装Windows Terminal和Linux系统(如Ubuntu)。接着,在控制面板中启用“适用于Linux的Windows子系统”并重启电脑。最后,在Windows Terminal中选择安装的Linux系统即可开始使用。文中还提供了注意事项和进一步配置的链接。
28 0
|
7月前
|
缓存 Linux 测试技术
安装【银河麒麟V10】linux系统--并挂载镜像
安装【银河麒麟V10】linux系统--并挂载镜像
2167 0
|
7月前
|
关系型数据库 MySQL Linux
卸载、下载、安装mysql(Linux系统centos7)
卸载、下载、安装mysql(Linux系统centos7)
254 0
|
2月前
|
Linux
手把手教会你安装Linux系统
手把手教会你安装Linux系统
|
5月前
|
Linux 虚拟化 数据安全/隐私保护
部署05-VMwareWorkstation中安装CentOS7 Linux操作系统, VMware部署CentOS系统第一步,下载Linux系统,/不要忘, CentOS -7-x86_64-DVD
部署05-VMwareWorkstation中安装CentOS7 Linux操作系统, VMware部署CentOS系统第一步,下载Linux系统,/不要忘, CentOS -7-x86_64-DVD
|
3月前
|
Ubuntu Linux 网络安全
从头安装Arch Linux系统
本文记录了作者安装Arch Linux系统的过程,包括安装成果展示和遇到的疑难点及其解决方法,如硬盘不足、下载失败、设置时区、安装微码和配置无密码登录等。
从头安装Arch Linux系统
|
4月前
|
存储 NoSQL Java
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
该博客文章展示了如何在Linux虚拟机上使用Redis和Jedis客户端实现手机验证码的验证功能,包括验证码的生成、存储、验证以及限制每天发送次数的逻辑,并提供了测试结果截图。
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)