锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. Linux
  4. Linux信号学习三步走及知识脉络

Linux信号学习三步走及知识脉络

0
  • Linux
  • 发布于 2024-09-29
  • 14 次阅读
黄健
黄健

Linux信号学习三步走及知识脉络

在Linux系统中,信号(Signal)是一个非常重要的概念,它作为一种异步通知机制,用于通知进程发生了某些事件。信号的本质是软件层次上对中断机制的一种模拟,是进程间通信机制中唯一的异步通信方式。学习Linux信号,可以通过以下三步走,并打通相关的知识脉络。

一、信号的基本概念与分类

1. 信号的定义

信号,又称为软中断信号,是Linux系统响应某些条件而产生的一个事件。它是操作系统向一个进程或者线程发送的一种异步通知,用于通知该进程或线程某种事件已经发生,需要做出相应的处理。信号本质是一种异步通知机制,用户或操作系统通过发送信号来通知进程某些事情已经发生,进程可以进行后续处理。

2. 信号的产生

信号可以由多种方式产生,包括:

  • 通过终端按键产生信号:例如,在终端上按Ctrl+C键通常产生中断信号(SIGINT),终止进程。
  • 调用系统函数向进程发信号 :如kill()函数、raise()函数等。
  • 由软件条件产生信号 :例如,使用alarm()函数设置的闹钟超时后会产生SIGALRM信号。
  • 硬件异常产生信号:如除数为0、无效的内存引用等,这些条件通常由硬件检测到,并通知内核,然后内核为发生此错误的进程发送相应的信号。

3. 信号的分类

Linux系统支持多种信号,大致可以分为两大类:非实时信号(也称为不可靠信号)和实时信号(也称为可靠信号)。非实时信号的值范围是1到31,是从UNIX系统中继承下来的;实时信号的值范围是34到64。非实时信号不支持排队,可能会丢失,而实时信号支持排队,可以确保信号按顺序处理。

可以使用kill -l命令查看系统中支持的所有信号及其编号和名称。每种信号都有其特定的含义和默认处理动作,例如,SIGKILL(信号值为9)的默认处理动作是立即终止进程,且不能被捕捉或忽略。

二、信号的处理与捕捉

1. 信号的处理方式

当进程接收到信号时,可以采取以下三种方式之一来处理信号:

  • 忽略信号:大部分信号都可以被忽略,但SIGSTOP和SIGKILL两个信号除外,因为它们是给超级用户提供杀掉或停止任何进程的手段。
  • 执行默认处理动作:系统为每种信号都定义了一个默认的处理动作,如终止进程、生成core dump文件等。
  • 捕捉信号:进程可以注册一个信号处理函数来捕捉特定的信号,并在接收到该信号时执行相应的处理逻辑。

2. 信号的捕捉

在Linux中,可以通过signal()函数或sigaction()函数来设置信号处理函数。signal()函数是UNIX系统的遗留接口,它相对简单但功能有限;而sigaction()函数提供了更丰富的功能,是更推荐使用的接口。

sigaction()函数允许进程为特定的信号指定一个处理函数,并可以修改信号的行为,如阻塞信号、查询信号等。其结构体sigaction包含了信号的处理函数、信号屏蔽字等信息。

示例代码:

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

void sig_handler(int signum) {

    printf("Caught signal %d\n", signum);
    // 清理资源、关闭文件等操作
    exit(signum);
}

int main() {

    struct sigaction act;
    act.sa_handler = sig_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    sigaction(SIGINT, &act, NULL);

    while(1) {

        printf("Looping...\n");
        sleep(1);
    }

    return 0;
}

在这个例子中,我们为SIGINT信号设置了处理函数sig_handler,当进程接收到SIGINT信号时,会执行sig_handler函数,并打印出接收到的信号编号,然后退出程序。

3. 信号的阻塞与解除

进程可以选择阻塞某些信号,被阻塞的信号在产生时将保持在未决状态,直到进程解除对该信号的阻塞,才执行递达的动作。信号的阻塞和解除可以通过sigprocmask()函数来实现。

sigprocmask()函数允许进程指定一个新的信号屏蔽字(即阻塞哪些信号),并可以获取旧的信号屏蔽字。通过设置信号屏蔽字,进程可以控制哪些信号被阻塞,哪些信号被允许递达。

三、信号的保存与递达

1. 信号的保存

Linux内核为每个进程维护了与信号相关的数据结构,主要包括三张表:阻塞表(Block表)、未决表(Pending表)和处理函数表(Handler表)。

  • 阻塞表:一个位图,用于表示进程当前阻塞了哪些信号。
  • 未决表:同样是一个位图,用于表示进程当前有哪些信号处于未决状态。
  • 处理函数表:一个函数指针数组,用于表示当信号递达时应该执行的处理动作。

当信号产生时,内核会在进程控制块(PCB)的Pending表中设置对应信号位的值为1,表示该信号已经产生且处于未决状态。然后,内核会检查Block表,查看该信号是否被阻塞。如果被阻塞,则信号会保持在未决状态;如果没有被阻塞,则根据Handler表中的处理函数指针执行相应的处理动作。

2. 信号的递达

信号的递达是指信号从产生到被处理的过程。在Linux中,信号的递达通常是在内核态和用户态之间切换时进行的。当进程从内核态返回到用户态时,内核会检查待处理的信号,并根据信号的处理方式执行相应的动作。

如果进程为某个信号设置了自定义处理函数,则在信号递达时,内核会切换到用户态并调用该处理函数。如果进程选择忽略信号或执行默认处理动作,则内核会根据相应的规则来处理信号。

四、总结与知识脉络

学习Linux信号需要打通以下知识脉络:

  1. 信号的基本概念:理解信号的定义、产生方式、分类以及默认处理动作。
  2. 信号的处理与捕捉 :掌握如何通过signal()函数或sigaction()函数来设置信号处理函数,并了解信号捕捉的机制和细节。
  3. 信号的阻塞与解除 :了解如何通过sigprocmask()函数来设置和修改进程的信号屏蔽字,从而控制哪些信号被阻塞或允许递达。
  4. 信号的保存与递达:理解Linux内核如何为进程维护信号相关的数据结构,以及信号从产生到递达的过程。

通过这三步走,可以系统地学习Linux信号的相关知识,并在实际编程中灵活运用信号机制来实现进程间的异步通信和错误处理。

原文链接: https://blog.csdn.net/hai40587/article/details/142553708

标签: #Linux 85
相关文章

【Linux】如何用shell脚本一键安装Java和Maven环境 2024-10-08 11:24

Shell脚本安装环境 前言 脚本 * Java安装脚本 * 使用方式 Java卸载脚本 Maven安装脚本 Maven卸载脚本 前言 无论是在云服务器上部署Java项目 还是在本地的Linux虚拟机上运行Java项目 都需要Java的环境 设置环境则需要一些繁琐的操作 为了简化并复用这些操作 我们

linux 网卡配置 2024-09-30 17:34

linux网卡可以通过命令和配置文件配置,如果是桌面环境还可以通过图形化界面配置. 1.ifconfig(interfaces config)命令方式 通常需要以root身份登录或使用sudo以便在Linux机器上使用ifconfig工具。依赖于ifconfig命令中使用一些选项属性,ifconfi

【Linux】进程间通信——System V共享内存 2024-09-30 17:34

目录 一、概念和原理 二、API介绍与使用 2.1 shmget 2.2 ftok 2.3 shmat 2.4 shmdt 2.5 shmctl

Linux如何修改时间和时区? 2024-09-30 17:34

Linux 修改时间 修改时区 * 时间修改 时区修改 时间修改 #查看时间 [root@localhost ~]# date 2024年 07月 08日 星期一 17:55:48 JST #设置时间 例:2024-07-08 18:00:00 [root@localhost ~]# date -

CentOS 修改服务器登录密码的完整指南 2024-09-30 17:34

个人名片 🎓作者简介 :java领域优质创作者 🌐个人主页 :码农阿豪 📞工作室 :新空间代码工作室(提供各种软件服务) 💌个人邮箱 :[2435024119@qq.com] 📱个人微信 :15279484656 🌐个人导航网站 :www.forff.top 💡座右铭:总有

虚拟机Ubuntu忘记密码 2024-09-30 17:34

Ubuntu重置密码 因为前几天虚拟机上刚安装的Ubuntu系统,密码忘记了,这次留个笔记记录一下。 有两种情况: 1、第一种 1、虚拟机上的Ubuntu开启,按住Shift键,直到出现下面的界面。(记住,一开启系统就长按Shift) 如果没有出现下面的界面,直接关闭Ubuntu,重新启动。 2、选

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.