【Linux从入门到精通】信号(初识信号 & 信号的产生)

这篇具有很好参考价值的文章主要介绍了【Linux从入门到精通】信号(初识信号 & 信号的产生)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理 

   本篇文章会对Linux下的信号进行详细解释。主要内容是什么是信号、信号的产生、核心转储等问题。希望本篇文章会对你有所帮助。

文章目录

引入

一、初识信号

1、1 生活中的信号

1、2 Linux 下的信号

1、3 信号+进程所得的初识结论

二、信号的产生

2、1 用户通过终端输入产生信号

2、1、1 理解组合键变成信号

2、1、2 验证ctrl + c 对应 (2)SIGINT信号 (signal()函数)

2、2 核心转储(拓展)

2、3 系统调用接口产生信号

2、4 软件条件产生信号

2、5 由硬件异常产生信号

三、总结


🙋‍♂️ 作者:@Ggggggtm 🙋‍♂️

👀 专栏:Linux从入门到精通  👀

💥 标题:信号产生💥

 ❣️ 寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景 ❣️  

引入

  在Linux系统中,信号是一种轻量级的通信机制,可以用于实现进程之间的协作和通信。每个信号都有一个唯一的编号,通常以SIG开头,例如SIGINT、SIGTERM等。这些信号的含义和行为在Linux系统中是标准化的,但也可以通过自定义信号处理程序来改变它们的行为。

  Linux信号在各种情况下都有广泛的应用,从终端用户通过Ctrl+C发送中断信号,到系统管理员使用信号来管理和监控进程,以及进程之间通过信号进行通信和协作。因此,理解Linux信号是系统管理员和开发人员的重要技能,有助于更好地控制和管理Linux系统中的进程。

一、初识信号

1、1 生活中的信号

  其实在生活中,我们也经常有意无意的接受信号。比如,玩游戏时队友发送的请求集合、订购外卖时快递员到了你楼下给你打电话,你也收到快递到来的通知等等。古代战争传递信号的方式是烽烟(烽火)。

  但是当你收到信号时,你就会立即处理吗?实际上可能并不会。例如,外卖到了但是你正在打游戏,需5min之后才能去取快递。那么在在这5min之内,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的行为并不是一定要立即执行,可以理解成“在合适的时候去取”

  我们接收到信号,并且处理时会有很多处理方法。例如我们取回来快递,就要开始处理快递了。而处理快递一般方式有三种:

  1. 执行默认动作(幸福的打开快递,使用商品);
  2. 执行自定义动作(快递是零食,你要送给你你的女朋友);
  3. 忽略快递(快递拿上来之后,扔掉床头,继续开一把游戏。

1、2 Linux 下的信号

  Linux信号通常由操作系统或其他进程发送给目标进程,可以用于多种目的,例如中断进程、终止进程或请求进程执行某个特定操作本质是一种通信机制

  标准信号是一组在Linux系统中具有固定编号和含义的信号。举个例子:我们平常在Linux下进程会使用Ctrl+C来终止当前的进程。这个本质就是向进程发送了一个2号信号。Linux下有很多信号,具体如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  实际上一共是有62个信号,因为并没有32号和33号信号。本篇文章重点讲解普通信号,也就是1~31号信号。还有一种信号是实时信号。实时信号是一组具有不同编号和含义的信号,通常用于高优先级任务和实时系统。实时信号的编号范围从34到64

  我们这里先给出普通信号的编号、名称和含义,下文也会对一些重点信号进行讲解:

  • SIGHUP(1): 挂起信号。
  • SIGINT(2): 中断信号。
  • SIGQUIT(3): 退出信号。
  • SIGILL(4): 非法指令信号。
  • SIGTRAP(5): 跟踪/陷阱信号。
  • SIGABRT(6): 中止信号。
  • SIGBUS(7): 总线错误信号。
  • SIGFPE(8): 浮点异常信号。
  • SIGKILL(9): 强制终止信号。
  • SIGUSR1(10): 用户自定义信号1。
  • SIGSEGV(11): 段错误信号。
  • SIGUSR2(12): 用户自定义信号2。
  • SIGPIPE(13): 管道破裂信号。
  • SIGALRM(14): 超时信号。
  • SIGTERM(15): 终止信号。
  • SIGSTKFLT(16): 协处理器栈错误信号。
  • SIGCHLD(17): 子进程状态改变信号。
  • SIGCONT(18): 继续执行信号。
  • SIGSTOP(19): 停止信号。
  • SIGTSTP(20): 终端停止信号。
  • SIGTTIN(21): 后台进程尝试读终端信号。
  • SIGTTOU(22): 后台进程尝试写终端信号。
  • SIGURG(23): 紧急情况信号。
  • SIGXCPU(24): 超出CPU时间限制信号。
  • SIGXFSZ(25): 超出文件大小限制信号。
  • SIGVTALRM(26): 虚拟定时器信号。
  • SIGPROF(27): 专用定时器信号。
  • SIGWINCH(28): 窗口大小改变信号。
  • SIGIO(29): 异步IO信号。
  • SIGPWR(30): 电源故障信号。
  • SIGSYS(31): 非法系统调用信号。

  通过上述Ctrl+C来终止当前的进程,那么这里会有一个疑问:进程为什么能够识别出用户所发送的信号呢?下面会给出一些结论。

1、3 信号+进程所得的初识结论

  同我们上述所列举的生活中的信号和Liunx下的信号,我们大概也能知道以下结论:

  • 进程要处理信号,必须具备信号“识别”的能力(看到+处理动作)。
  • 凭什么进程能够“识别”信号呢?原因是由于操作系统提供了信号处理机制,通过注册和处理信号处理函数,进程可以对不同的信号做出相应的响应和处理。根本上就是程序员已经在底层都处理好了
  • 信号产生是随机的,进程可能正在忙自己的事情,所以,信号的后续处理,可能不是立即处理的!
  • 进程会临时的记录下对应的信号,方便后续进行处理。
  • 在什么时候处理呢?合适的时候。(下文会详细解释)
  • 一般而言,信号的产生相对于进程而言是异步的

  什么是异步呢?异步是指事件的发生和处理是相互独立、不同步进行的。在计算机编程中,异步操作指的是程序在执行某个操作时,不需要等待该操作完成,而可以继续执行下面的代码,在操作完成后通过回调或其他方式得到结果

  举例来说,假设有一个在线聊天应用程序,用户可以发送消息给其他用户。当用户发送一条消息时,常见的做法是通过网络将消息发送给接收方,然后等待接收方的响应,最后再执行下一步操作。

  但如果使用异步的方式,则用户在发送消息之后可以继续进行其他操作,而不需要等待对方的响应。一旦对方接收到消息并做出处理,系统会通知发送方消息已经成功发送,或者提供相应的错误信息。

  这种异步的方式可以提高用户体验,因为用户不需要一直等待操作的完成,可以同时进行其他操作。同时也可以提高系统的并发性能,充分利用计算资源。

  在编程中,常见的异步操作包括网络请求、文件读写、数据库操作等。通过使用异步操作,可以避免因阻塞等待而导致程序性能下降或产生无响应的情况,提升程序的效率和响应速度。

二、信号的产生

  我们大概了解信号的概念后,再来看一下信号都是在哪些情况下产生的。在Linux下,信号可以由多种方式产生。以下是一些常见的信号产生方式:

  1. 用户通过终端输入:例如按下Ctrl+C键产生的SIGINT信号,用于中断进程的执行。
  2. 硬件异常:当发生硬件故障或错误时,操作系统会发送相应的信号给进程,例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
  3. 软件条件:进程可以根据满足特定条件时发送信号给自己或其他进程。本篇文章主要介绍alarm函数 和SIGALRM信号。
  4. 系统调用:某些系统调用可以触发信号。例如,kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定的信号。

  下面会对每种产生信号的方式进行详解。

2、1 用户通过终端输入产生信号

2、1、1 理解组合键变成信号

  上述了解到了:Ctrl+C产生(2)SIGINT信号。但是组合键怎么就变成信号了呢

  我们可以简单了理解为:Ctrl+C产生SIGINT信号的行为只是命令行界面中的一种约定。具体是:用户按下Ctrl+C后,键盘输入产生一个硬件中断,被OS获取(OS能识别我们所输入的组合键),解释成信号,发送给目标前台进程,前台进程因为收到信号,进而引起进程退出。

  在上述的情况中,我们知道了操作系统解释完后将信号发送给了进程。那么信号是保存在哪里呢?答案是对应进程的数据结构位图中!下文也会对此进行详解。那么发送信号的本质是操作系统向进程中写信号,不就是修改对应的进程控制块(PCB)中的内核位图数据结构吗!!!

2、1、2 验证ctrl + c 对应 (2)SIGINT信号 (signal()函数)

  在验证之前,我们先来学习一下signal()函数的使用。signal()函数是一个用于处理信号的函数,它允许我们定义信号处理程序来捕获和处理系统中产生的各种信号。具体如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

下面是signal()函数的参数解释:signumhandlerSIGINT

参数:

  1. signum:表示要捕获或处理的信号编号。例如,SIGINT表示键盘中断信号。
  2. handler:表示信号处理程序的指针。它可以是一个指向函数的指针,也可以是某些特定的常量。我们也可以自定义handler。
    • 如果handler的值为SIG_IGN,表示忽略对该信号的处理。
    • 如果handler的值为SIG_DFL,表示使用默认的信号处理方式

  我们在对第二参数进行解释一下。在上文中也提到过信号的处理方式:1、默认。2、忽略。3、自定义捕捉。当我们传入自定义函数时,该信号就会进行自定义捕捉

  下面是一个详细的示例使用signal函数来验证ctrl + c 对应 (2)SIGINT信号 : 

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

void signal_handler(int signum) {
    printf("Received signal: %d\n", signum);
}

int main() {
    // 设置信号处理函数
    signal(SIGINT, signal_handler);

    printf("Signal handling example. Press Ctrl+C to send a SIGINT signal.mypid:%d\n",getpid());

    // 进入一个循环,在循环中不进行任何操作,等待信号发生
    while(1)
    {
        sleep(1);
    }

    return 0;
}

在这个示例中,我们定义了一个信号处理函数signal_handler,该函数在收到信号时会被调用,并打印接收到的信号编号。

  接下来,在主函数main中,我们通过调用signal函数来设置对SIGINT信号(即Ctrl+C)的处理方式。将signal(SIGINT, signal_handler)作为参数传递给signal函数,表示在接收到SIGINT信号时,调用signal_handler函数进行处理。

  然后,我们输出一个提示信息,并进入一个无限循环,在循环中不进行任何操作,只是通过sleep函数暂停一秒钟,等待信号的发生。

  当我们在运行程序时,按下Ctrl+C组合键,会发送SIGINT信号。这时,由于我们设置了对SIGINT信号的处理方式为调用signal_handler函数,所以程序会输出"Received signal: 2"(2为SIGINT的信号编号)的消息,并且程序也不会终止。表示成功捕获并处理了SIGINT信号。具体如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  signal函数,仅仅是修改进程对特定信号的后续处理动作,不是直接调用对应的处理动作。如果后续没有任何SIGINT信号产生,signal_handler会不会被调用呢?答案是永远也不会被调用。当只有SIGINT信号产生时,才会调用signal_handler函数。

2、2 核心转储(拓展)

  在Linux下,我们可通过指令:man 7 signal ,来查看信号的详细信息。如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  我们直观的看到,Action中有:Term、Core、Ign、Cont、Stop。在其中主要是Term、Core两种。Term 就是终止的意思。那么Core呢?Core也是有终止的意思,但是在终止进程前,还会生成一个核心转储(core dump)文件

  我们在进程等待(进程的控制(进程退出+进程等待))中提到过,但是并没有进行详细解释。具体如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  那么回到我们的问题:核心存储是什么呢?用来干什么的呢?我们接着往下看。

  核心转储(core dump)是指在计算机系统中,当发生严重错误或异常情况导致程序无法正常运行时,系统会将程序当前的内存状态和相关信息保存到一个磁盘文件中,该文件就被称为核心转储文件(core dump file)。核心转储文件包含了程序崩溃时的堆栈信息、寄存器状态、全局变量值等关键信息。通过分析核心转储文件,可以帮助开发人员或调试人员确定程序崩溃的原因和位置,并进行问题排查和调试

  但是,在我们的云服务器上,核心存储功能是被关闭的。一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存 在PCB中)。默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。
  当然,我们可先查看一下是否能够形成核心存储文件。指令为:ulimit -a。如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  默认核心存储文件最大为0kb。是不可生成的。可以通过指令:ulimit -c 10240 ,来修改默认核心存储文件的最大值。具体如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  我们就行 (3) SIGQUIT信号来测试。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int main() {
    // 设置信号处理函数
    signal(SIGQUIT, SIG_DFL);


    // 进入一个循环,在循环中不进行任何操作,等待信号发生
    while(1)
    {
        sleep(1);
    }

    return 0;
}

  信号(3) SIGQUIT 所对应的组合键为 ctrl+‘\’。我们来看一下运行结果:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  为了让结果更加直观,我们不放创建子进程,然后用特殊的方式让子进程退出,再将子进程的退出信号和core dump 标志打印出来。具体结合下图和代码理解:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        cout << "i am child:" << getpid()<< endl;
        sleep(1);
        int a = 100;
        a /= 0;
        exit(0);
    }

    cout<<"i am father:"<<getpid()<<endl;
    int status = 0;
    waitpid(id, &status, 0);
    cout << "父进程:" << getpid() << " 子进程:" << id << \ 
    " exit sig: " << (status & 0x7F) << " is core: " << ((status >> 7) & 1) << endl;
    return 0;
}

  上述代码中有一个除0错误。而它发生时,会产生(8)SGIGFPE 信号,也会发生核心转储。运行结果如下:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

  我们看到了退出信号确实为8,且core dump标记为变成1。表示发生了核心转储。那么生成的核心转储文件有什么用呢?我们可通过调试,加载核心转储文件后可直接看到所对应的错误信息。指令是:core-file core.27736。具体如下图:

【Linux从入门到精通】信号(初识信号 & 信号的产生),Linux从入门到精通,linux,信号,信号处理

2、3 系统调用接口产生信号

  如何理解系统调用接口产生信号呢?首先是我们用户进行系统调用接口,然后操作系统会执行对应的系统代码。其中操作系统会自动提取我们所传入的参数,再向目标进程写信号。也就是修改对应进程的位图数据结构。最后进程会进行相关的处理操作。

  系统调用接口也可用于产生各种不同类型的信号。下面列举了几个常见的系统调用接口,它们可用于产生不同的信号:

  1. kill(pid, sig): 这个系统调用接口用于向指定进程发送SIGKILL信号。通过指定pid参数为目标进程的进程ID,通过sig参数指定要发送的信号。

  2. raise(sig): 这个系统调用接口用于向当前进程自身发送信号。通过指定sig参数来选择要发送的信号。

  3. abort():SIGABRT可以被捕捉,但是捕捉之后依然会让进程终止,这就是SIGABRT的特点就像exit函数一样,abort函数总是会成功的,所以没有返回值。

  4. sigaction(sig, new_action, old_action): 这个系统调用接口用于设置信号处理程序。通过指定sig参数表示要设置的信号,通过new_action参数传递新的信号处理程序,通过old_action参数获取之前的信号处理程序。

  下文我们也会用到系统调用接口产生相应的信号。

2、4 软件条件产生信号

  当一个程序通过软件条件产生信号时,它可以通知其他程序或系统内核发生了某个特定的事件或状态的改变。以下是一个例子来详细解释这个过程:

  假设我们有一个服务管理程序,该程序负责监控某个服务器上的各种服务的运行情况。服务管理程序需要检查每个服务是否正常运行,如果发现某个服务停止工作,它应该发送一个信号给系统管理员,以便及时采取措施解决问题。

  下面我们来看一个用alarm产生信号。代码如下:

typedef function<void ()> func;
vector<func> callbacks;

uint64_t count = 0;


void showCount()
{
    // cout << "进程捕捉到了一个信号,正在处理中: " << signum << " Pid: " << getpid() << endl;
    cout << "final count : " << count << endl;
}
void showLog()
{
    cout << "这个是日志功能" << endl;
}
void logUser()
{
    if(fork() == 0)
    {
        execl("/usr/bin/who", "who", nullptr);
        exit(1);
    }
    wait(nullptr);
}

void catchSig(int signum)
{
    for(auto &f : callbacks)
    {
        f();
    }
    alarm(1);
}
static void Usage(string proc)
{
    cout << "Usage:\r\n\t" << proc << " signumber processid" << endl;
}



int main(int argc, char *argv[])
{
    
    signal(SIGALRM, catchSig);
    callbacks.push_back(showCount);
    callbacks.push_back(showLog);
    callbacks.push_back(logUser);

    alarm(1);
    
    while(true) count++;

    return 0;
}

  这段代码是一个示例程序,它使用了信号处理、回调函数和进程控制相关的操作。下面对代码进行详细解释:

  1. 首先,定义了一个函数指针类型func,该类型表示一个无返回值、无参数的函数。
  2. 创建了一个名为callbacks的向量(vector),用于存储回调函数。
  3. 定义了一个名为count的64位整数变量,初始值为0。
  4. 定义了三个函数:showCount()showLog()logUser(),分别用于显示count的值、打印日志和查看当前登录用户。
  5. catchSig()函数用于捕获信号,并依次调用存储在callbacks中的回调函数。在本例中,catchSig()会被设置成SIGALRM信号的处理函数。
  6. Usage()函数用于显示程序的使用方法。
  7. main()函数中,首先注册了SIGALRM信号的处理函数为catchSig()
  8. 接下来,将showCount()showLog()logUser()这三个函数添加到callbacks中。
  9. 调用alarm(1)函数,设置一个定时器,每隔1秒钟触发一次SIGALRM信号,从而调用catchSig()函数。
  10. 使用一个无限循环,不断递增count的值。

  整个程序的运行过程如下:

  1. 注册SIGALRM信号处理函数catchSig()
  2. showCount()showLog()logUser()这三个函数添加到callbacks中。
  3. 调用alarm(1)设置定时器,1秒后触发SIGALRM信号,并调用catchSig()函数。
  4. catchSig()函数中,依次调用存储在callbacks中的函数。
  5. showCount()函数会显示当前count的值,showLog()函数会打印日志信息,logUser()函数会通过创建子进程调用/usr/bin/who命令查看当前登录用户。
  6. 定时器再次启动,继续循环执行。

2、5 由硬件异常产生信号

  除0错误就是硬件异常。包括对野指针的访问修改,也是硬件异常产生信号来终止程序的。

  为什么说除0是硬件异常错误呢?所有的计算操作都是在cpu中进行的,cpu中有一个状态寄存器(对外是不可见的,也是不可被修改的),寄存器内有对应的状态标记位(溢出标记位)。OS会自动进行计算完毕之后的检测的!如果溢出标记位是1,OS里面识别到有溢出问题,立即只要找到当前谁在运行提取PID,OS完成信号发送的过程,进程会在合适的时候,进行处理即可

  如何理解野指针或者越界问题呢?

  首先都必须通过地址,找到目标位置。我们语言上面的地址,全部都是虚拟地址。将虚拟地址转成物理地址。转换的过程中需要通过页表+MMU(Memory Manager Unit,硬件! ! )。在转换时,发现野指针是越界访问或者非法地址。MMU转化的时候,一定会报错!此时就会发出信号来终止程序

  注意:一旦出现硬件异常,进程一定会退出吗?不一定!一般默认是退出,但是我们即便不退出,我们也做不了什么。当我们不退出时,但也并没有对异常进行任何修改,寄存器中任然保留异常。则会进入死循环报错。

三、总结

  本篇文章详细解释了信号是怎么产生的。并且知道了写信号的本质就是修该进程控制块内容等等。

  而我们还留下了一系列问题:在合适的时候会处理信号。这里的合适的时候具体是什么呢?同时信号的保存还有很多细节没有讲解。还有最后的信号处理工作也没有详解。我们会在下篇文章进行详细解释!!!感谢阅读ovo~文章来源地址https://www.toymoban.com/news/detail-706372.html

到了这里,关于【Linux从入门到精通】信号(初识信号 & 信号的产生)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux进程信号【信号处理】

    ✨个人主页: 北 海 🎉所属专栏: Linux学习之旅 🎃操作环境: CentOS 7.6 阿里云远程服务器 从信号产生到信号保存,中间经历了很多,当操作系统准备对信号进行处理时,还需要判断时机是否 “合适”,在绝大多数情况下,只有在 “合适” 的时机才能处理信号,即调用信号

    2024年02月11日
    浏览(39)
  • Linux进程信号 | 信号处理

    前面的文章中我们讲述了信号的产生与信号的保存这两个知识点,在本文中我们将继续讲述与信号处理有关的信息。 之前我们说过在收到一个信号的时候,这个信号不是立即处理的,而是要得到的一定的时间。从信号的保存中我们可以知道如果一个信号之前被block,当解除

    2024年02月09日
    浏览(41)
  • 【Linux】进程信号之信号的处理

    在前面我们讲过信号产生和保存以后,我们知道进程对于产生的信号不是立即去处理的,而是在\\\"合适\\\"的时候去处理信号, 这是因为信号的产生的异步的,当前进程可能正在做更重要的事情!。 那么信号可以被立即处理吗?答案的可以的,但是要满足这个条件: 在 Linux 中如果

    2024年02月12日
    浏览(50)
  • 【Linux从入门到精通】信号量(信号量的原理与相关操作接口)详解

      本篇文章重点对 信号量的概念,信号量的申请、初始化、释放、销毁等操作进行讲解。同时举例把信号量应用到生产者消费者模型来理解 。希望本篇文章会对你有所帮助。 目录 一、信号量概念 1、1 什么是信号量 1、2 为什么要有信号量 1、3 信号量的PV操作 二、信号量的相

    2024年02月08日
    浏览(47)
  • 【linux】进程信号——信号的保存和处理

    上一章主要讲述了信号的产生:【linux】进程信号——信号的产生 这篇文章主要讲后面两个过程。 实际执行信号的处理动作称为 信号递达 (Delivery)。 信号从产生到递达之间的状态,称为 信号未决 (Pending)。 因为信号 不是被立即处理的 ,所以在信号产生之后,递达之前的这个

    2024年02月03日
    浏览(38)
  • 【Linux】进程信号 -- 信号保存与递达 | 信号捕捉 | 僵尸进程的信号处理方法

    实际执行信号的处理动作称为信号递达(Delivery) 信号从产生到递达之间的状态,称为信号未决(Pending)。 已经收到但未处理的状态 进程可以选择阻塞 (Block )某个信号 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作 注意,阻塞和忽略是

    2024年02月16日
    浏览(45)
  • 【Linux学习】信号——信号保存 | 信号处理 | 不可重入函数,volatile,SIGCHLD信号

    🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言: 你只管努力,剩下的交给时间! 信号的产生以及详细讲解了,有兴趣的小伙伴可以去看看,传送门。接下来介绍信号的保存和信号处理。 首先介绍几个新的概念: 信号递达(Delivery):实际执行信号的处理动作。 信号

    2023年04月14日
    浏览(42)
  • linux信号处理机制

            信号检测是项目开发中必不可少的!提到信号处理机制,很多人都会想到signal函数吧         除了这种方式,还有一种操作信号集的方式更为精确,能够屏蔽,添加,删除,操作等某个信号。这些函数仅支持对 POSIX 信号集进行操作。首先了解下这几个函数: 描

    2024年01月23日
    浏览(43)
  • Linux进程 ----- 信号处理

    目录 前言 一、信号的处理时机 1.1 处理时面临的情况 1.2 “合适”的时机 二、用户态与内核态 2.1 概念理论 2.2 再现 进程地址空间 2.3 信号处理过程 三、信号的捕捉 3.1 内核实现 3.2 sigaction 四、信号部分小结 从信号产生到信号保存,中间经历了很多,当操作系统准备对信号进

    2024年03月21日
    浏览(75)
  • Linux——信号处理

    在Linux系统中, 信号处理 是一个非常重要的概念,它允许 操作系统在特定事件发生时 通知进程。信号可以由 硬件异常、用户输入、软件条件 等多种来源产生。为了有效地处理这些信号,Linux提供了一系列的系统调用和函数,其中 signal 、 sigaction 和 sigprocmask 是三个核心的函

    2024年03月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包