Linux中信号是什么?Ctrl + c后到底为什么会中断程序?

简介: 信号在进程的学习中是一个非常好用的存在,它是软件层次上对中断机制的一种模拟,是异步通信方式,同时也可以用来检测用户空间到底发生了什么情况,然后系统知道后就可以做出相应的对策。

 

目录

信号的基本特征:

实际应用场景:

使用信号的注意事项:

信号的种类:

信号的三大类型:

源码:


信号在进程的学习中是一个非常好用的存在,它是软件层次上对中断机制的一种模拟,是异步通信方式,同时也可以用来检测用户空间到底发生了什么情况,然后系统知道后就可以做出相应的对策。

在Linux系统中,信号(Signal)是一种进程间通信(IPC)的方式,它用于通知进程发生了某个特定的事件。信号机制允许操作系统或一个进程向另一个进程发送异步通知,以此来控制进程的行为。信号是软中断,可以打断进程的正常流程,迫使其提前处理信号所代表的事件。以下是关于Linux信号的一些基本概念和要点:

信号的基本特征:

  1. 信号的命名:Linux中的信号通常以“SIG”前缀开始,例如SIGINT(中断,通常由Ctrl+C触发)、SIGTERM(终止进程)、SIGHUP(挂起)、SIGKILL(强制终止进程)等。每个信号都有一个对应的数字编号。
  2. 信号处理:进程可以有三种方式处理信号:
  • 默认处理:大多数信号有默认行为,比如SIGINT会使进程终止。
  • 忽略:进程可以选择忽略某些信号,但某些关键信号如SIGKILL和SIGSTOP不能被忽略。
  • 自定义处理:通过信号处理函数(signal handler)来指定信号到达时执行的特定操作。
  1. 信号发送:进程可以通过kill系统调用向自己或其他进程发送信号。内核也会在特定情况下自动发送信号,比如用户操作(如按下Ctrl+C)或硬件异常。
  2. 信号阻塞与未决:进程可以通过sigprocmask等函数临时阻塞对某些信号的接收,直到它解除阻塞。同时,未决信号是指已发送但尚未被进程处理的信号,这些信号会被排队等待处理。
  3. 信号与系统调用的关系:信号的处理通常与当前执行的系统调用无关,信号处理可以中断正常的程序执行流程,执行完信号处理函数后,可以选择恢复原系统调用(如果支持)或直接返回到用户态。

实际应用场景:

  • 用户中断:用户通过键盘(如Ctrl+C)发送SIGINT来中断一个正在运行的命令或进程。
  • 程序终止:系统管理员或程序本身使用SIGTERM来请求进程正常退出。
  • 程序重启:SIGHUP信号常用于通知进程重新加载配置文件或重启。
  • 调试:SIGTRAP等信号用于调试目的,可以捕获并分析程序状态。

使用信号的注意事项:

  • 信号处理函数应当简短且安全,避免在其中执行长时间或阻塞的操作。
  • 某些信号(如SIGKILL和SIGSTOP)不能被捕获或忽略,以确保系统能够控制进程。
  • 合理设计信号处理逻辑,避免信号处理时的竞态条件和死锁。

理解信号及其机制对于编写健壮的Linux应用程序至关重要,尤其是在需要处理外部事件或异常情况的场景下。

信号的种类:

SIGINT:结束进程,对应快捷方式ctrl+c

SIGQUIT:退出信号,对应快捷方式ctrl+\

SIGKILL:结束进程,不能被忽略不能被捕捉

SIGTERM:结束终端进程,kill 使用时不加数字默认是此信号

SIGCHLD:子进程状态改变时给父进程发的信号

SIGSTOP:暂停进程,不能被忽略不能被捕捉

SIGTSTP:暂停信号,对应快捷方式ctrl+z

SIGALRM:闹钟信号,alarm函数设置定时,当到设定的时间时,内核会向进程发送此信号结束进程。

信号的三大类型:

1)忽略信号:对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。

2)捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数。

3)执行缺省操作:Linux对每种信号都规定了默认操作 。

这个程序是运用了信号的一个顺序的简单小程序,我们只需要把逻辑顺清,谁应该接收什么信号,做什么处理,忽略什么信号就可以写出,但是有一点要注意的是如何获取父进程和子进程的ID号。

getPPID:获取父进程ID号

getPID:获取子进程ID号

值得一提的是虽然子进程复制了父进程几乎所有的东西,但是他们的ID号是不同的

用信号的知识实现司机和售票员问题。

1)售票员捕捉SIGINT(代表开车)信号,向司机发送SIGUSR1信号,司机打印(let's gogogo)

2)售票员捕捉SIGQUIT(代表停车)信号,向司机发送SIGUSR2信号,司机打印(stop the bus)

3)司机捕捉SIGTSTP(代表到达终点站)信号,向售票员发送SIGUSR1信号,售票员打印(please get off the bus)

4)司机等待售票员下车,之后司机再下车。

源码:

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
pid_t pid;
void hanlder1(int sig)
{
    if(sig == SIGINT)
    {   
        kill(getppid(), SIGUSR1);// getppid() 是父进程的号
    }
    if(sig == SIGQUIT)
    {
        kill(getppid(), SIGUSR2);
    }
    if(sig == SIGUSR1)
    {
        printf("get off the bus\n");
        exit(0);
    }
    
}
void hanlder2(int sig)
{
    if(sig == SIGUSR1)
    {
        printf("let's gogogo\n");
    }
    if(sig == SIGUSR2)
    {
         printf("stop the bus\n");
    }
    if(sig == SIGTSTP)
    {
        kill(pid,SIGUSR1);// pid 是子进程的号
        wait(NULL);
        exit(0);
    }
}
int main(int argc, char const *argv[])
{
    pid = fork();
    if (pid < 0)
    {
        perror("pid open error");
        return -1;
    }
    else if (pid == 0)
    {
        while (1)
        {
            signal(SIGTSTP,SIG_IGN);// 忽略SIGTSTP
            signal(SIGINT, hanlder1);// 捕获SIGINT
            signal(SIGQUIT, hanlder1);//捕获SIGQUIT
            signal(SIGUSR1, hanlder1);//捕获SIGUSR1
            pause();
        }
    }
    else
    {
        while (1)
        {
            signal(SIGINT, SIG_IGN);// 忽略SIGINT
            signal(SIGQUIT, SIG_IGN);// 忽略SIGQUIT
            signal(SIGUSR1, hanlder2);//捕获SIGUSR1
            signal(SIGUSR2, hanlder2);//捕获SIGUSR2
            signal(SIGTSTP, hanlder2);//捕获STGTSTP
            pause();
        }
    }
}

image.gif


相关文章
|
2天前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
|
20天前
|
Linux 程序员 芯片
【Linux驱动】普通字符设备驱动程序框架
【Linux驱动】普通字符设备驱动程序框架
|
2天前
|
Linux 数据安全/隐私保护 iOS开发
Linux的root用户,普通用户无法在根录中创建文件,一般在其HOME目录里是不受限的,一旦出了HOME目录,大多数地方,仅有读和执行的权限,ctrl + d回到上一个用户,Exit,su - ro
Linux的root用户,普通用户无法在根录中创建文件,一般在其HOME目录里是不受限的,一旦出了HOME目录,大多数地方,仅有读和执行的权限,ctrl + d回到上一个用户,Exit,su - ro
|
2天前
|
运维 监控 大数据
部署-Linux01,后端开发,运维开发,大数据开发,测试开发,后端软件,大数据系统,运维监控,测试程序,网页服务都要在Linux中进行部署
部署-Linux01,后端开发,运维开发,大数据开发,测试开发,后端软件,大数据系统,运维监控,测试程序,网页服务都要在Linux中进行部署
|
10天前
|
缓存 Linux 编译器
技术笔记:Linux程序包管理
技术笔记:Linux程序包管理
|
10天前
|
Java 编译器 Linux
程序技术好文:详解Linux安装GCC方法
程序技术好文:详解Linux安装GCC方法
21 0
|
12天前
|
Linux
【Linux】进程信号_1
【Linux】进程信号_1
7 0
|
2天前
|
Linux 网络安全 开发工具
linux 常用命令【编程必备】
linux 常用命令【编程必备】
14 4
|
2天前
|
存储 Linux
Linux文件的上和下,FinalShell文件右键可下文件,先选择root文件夹,然后把他文件往里面拖动,就可以下载了,命令下载,ls -l可以看当前文件目录,sz 文件名可下载,tab补,rz出上
Linux文件的上和下,FinalShell文件右键可下文件,先选择root文件夹,然后把他文件往里面拖动,就可以下载了,命令下载,ls -l可以看当前文件目录,sz 文件名可下载,tab补,rz出上