首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux 信号屏蔽与恢复

Linux 信号屏蔽与恢复基础概念

在Linux操作系统中,信号(Signals)是一种用于进程间通信的机制。信号可以由内核、其他进程或者系统事件产生,并且可以被进程捕获和处理。信号屏蔽(Signal Masking)是指暂时阻止某些信号被进程接收,而信号恢复(Signal Unmasking)则是解除这种阻止,使信号能够再次被进程接收。

相关优势

  1. 避免竞态条件:通过屏蔽信号,可以确保在执行关键代码段时不会被信号中断,从而避免竞态条件。
  2. 提高程序稳定性:屏蔽某些可能导致程序崩溃的信号,可以提高程序的稳定性。
  3. 精确控制:允许开发者精确控制哪些信号在何时被处理,从而实现更复杂的逻辑。

类型

常见的信号包括:

  • SIGINT:由用户按下Ctrl+C产生。
  • SIGTERM:请求进程终止。
  • SIGKILL:强制终止进程,无法被捕获或忽略。
  • SIGSTOP:暂停进程执行。
  • SIGCONT:继续执行被暂停的进程。

应用场景

  1. 后台任务处理:在执行长时间运行的任务时,可能需要屏蔽某些信号以防止意外中断。
  2. 系统初始化脚本:在系统启动时,可能需要屏蔽某些信号以确保关键步骤的顺利完成。
  3. 多线程编程:在多线程环境中,正确处理信号可以避免线程间的冲突。

示例代码

以下是一个简单的示例,展示如何在C语言中屏蔽和恢复信号:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void handle_signal(int sig) {
    printf("Received signal %d\n", sig);
}

int main() {
    sigset_t mask;
    struct sigaction sa;

    // 初始化信号集
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);  // 屏蔽SIGINT信号

    // 设置信号处理函数
    sa.sa_handler = handle_signal;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    sigaction(SIGINT, &sa, NULL);

    // 屏蔽信号
    pthread_sigmask(SIG_BLOCK, &mask, NULL);

    printf("Signal masking started. Press Ctrl+C to test.\n");
    sleep(10);  // 模拟长时间任务

    // 恢复信号
    pthread_sigmask(SIG_UNBLOCK, &mask, NULL);

    printf("Signal unmasked. Press Ctrl+C again to test.\n");
    sleep(10);

    return 0;
}

遇到的问题及解决方法

问题:信号屏蔽后无法恢复

原因:可能是由于信号集设置错误或者在恢复信号时使用了错误的标志。

解决方法

  1. 确保在屏蔽信号时正确设置了信号集。
  2. 使用pthread_sigmask函数时,确保传递正确的标志(如SIG_UNBLOCK)。

问题:信号处理函数未被调用

原因:可能是由于信号被屏蔽或者在设置信号处理函数时出错。

解决方法

  1. 检查信号是否被正确屏蔽和恢复。
  2. 确保使用sigaction函数正确设置了信号处理函数。

通过以上方法,可以有效管理和控制Linux系统中的信号,确保程序的稳定性和可靠性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Linux】详解信号的保存&&信号屏蔽字的设置

称为信号集,可以用来修改进程block位图中的信号屏蔽字。...3.2、设置信号屏蔽字 利用sigprocmask系统调用函数可以设置进程的信号屏蔽字 第一个参数how有三个选项: SIG_BLOCK:set包含了我们希望添加到当前信号屏蔽字中的信号,相当于mask...SIG_SETMASK:设置当前信号屏蔽字为set所指向的值,相当于mask=set。 第二个参数set是我们设置的信号屏蔽字,第三个参数为输出型信号屏蔽字,是原来的信号屏蔽字。...3.3、设置信号屏蔽字的例子 下面是一个设置屏蔽2号信号,有解除屏蔽2号信号的例子。...,程序到20秒时退出: 四、总结 31个信号中并不是所有信号都可以被屏蔽掉,9号信号(SIGKILL)和19号信号(SIGSTOP)是无法被屏蔽掉的。

15810

如何屏蔽SIGPIPE信号

#include #include //默认读写一个关闭的socket会触发sigpipe信号 该信号的默认操作是关闭进程 有时候这明显是我们不想要的...//所以此时我们需要重新设置sigpipe的信号回调操作函数 比如忽略操作等 使得我们可以防止调用它的默认操作 //信号的处理是异步操作 也就是说 在这一条语句以后继续往下执行中如果碰到信号依旧会调用信号的回调处理函数...//处理sigpipe信号 void handle_for_sigpipe() { struct sigaction sa; //信号处理结构体 memset(&sa, '\...启动另一个Linux终端并执行killall -SIGPIPE sigpipe,可以发现sigpipe程序的默认操作关闭进程并未执行。...再次启动另一个Linux终端并执行killall -SIGPIPE sigpipe,可以发现sigpipe程序退出了。

1.1K31
  • 【Linux】信号概念与信号产生

    信号概念与信号产生 一、初识信号 1. 信号概念 生活中类似信号的概念也不少,例如上课铃声响,就是信号的发出,我们听到上课铃声,就是接收到信号,我们快速回到教室上课就是对信号做出处理。...此时我们运行程序,我们可以输入指令,bash 可以接收我们的指令,也就是说我们还能正常使用 bash 命令行,但是此时我们使用 ctrl + c 就杀不掉该进程了,这种进程我们称为后台进程,如下图: 在Linux...我们可以查看Linux中的信号列表,指令为: kill -l 其中我们发现,0号、32号和33号信号是没有的。...也就是一共有62个信号;其中我们把 1~31 号信号称为普通信号;往后的称为实时信号,当信号产生必须立即处理就是实时信号;其中我们只学习普通信号。...所以CPU在进行调度运行的时候,一旦出现异常了,对应的状态寄存器由0置1了,该进程是否出异常与进程切换无关,也就是说,该进程必定是出异常了,但是它不会影响其它进程,因为出异常的数据是属于当前进程的上下文

    19810

    【Linux】信号保存与信号捕捉处理

    信号保存与信号捕捉 一、信号保存 1....; void (*sa_restorer)(void); }; 以上的五个字段中,我们只需要知道第一个字段 sa_handler 和第三个字段 sa_mask 即可,其它都是与实时信号有关的字段...(3)struct sigaction 中的 sa_mask 字段 当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时...正如我们上面所说,如果正在处理2号信号,2号信号会被屏蔽,那么如果还希望自动屏蔽另外一些信号,则用 sa_mask 字段说明这些需要额外屏蔽的信号,当信号处理函数返回时会自动恢复原来的信号屏蔽字。...我们在给 sa_mask 字段说明需要屏蔽哪些信号时,需要使用 sigaddset 设置信号集,然后往 sa_mask 中设置即可,例如,添加屏蔽3号信号: sigaddset(&act.sa_mask

    18711

    【Linux进程信号】Linux信号机制深度解析:保存与处理技巧

    前言:在Linux操作系统的广阔天地中,信号机制无疑是一个充满挑战与机遇的领域。信号,作为进程间通信的一种重要方式,不仅承载着丰富的信息,还扮演着进程控制与管理的重要角色。...然而,对于许多初学者而言,信号的保存与处理往往是一个难以逾越的障碍 本文旨在为广大Linux学习者提供一份详尽而实用的指南,帮助他们深入理解Linux中的信号机制,掌握信号的保存与处理技巧。...我们将从信号的基本概念出发,逐步深入到信号的捕获、保存、处理以及恢复等各个环节,通过生动的实例和详细的解释,让读者能够轻松掌握这一复杂而强大的功能 让我们一同踏上这段充满探索与发现的旅程,共同揭开Linux..., &oact); while(1) sleep(1); return 0; } 当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字...在处理函数中,父进程使用waitpid()函数来回收子进程的资源 随着我们对Linux中信号保存与处理机制的深入探讨,我们不难发现,信号不仅是进程间通信的一种重要手段,更是Linux操作系统内核提供的一种强大而灵活的控制机制

    16410

    【Linux】信号>信号产生&&信号处理&&信号保存&&信号详解

    Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里 3.3 sigset_t 从上图来看,每个信号只有一个bit的未决标志,非0即1,不记录该信号产生了多少次...如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。如果oset和set都是非空指针,则先将原来的信号 屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。...void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; sigaction函数可以读取和修改与指定信号相关联的处理动作...显然,这也是一个回调函数,不是被main函数调用,而是被系统所调用 当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时...如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字 void Print(sigset_t

    18410

    【Linux】:进程信号(信号保存 & 信号处理)

    (与Pending位图类似,Block位图用于记录哪些信号被进程阻塞。...Linux的实现:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里 信号阻塞和未决的区别 信号阻塞(Blocking):是一个开关动作,指的是阻止信号被处理,但不是阻止信号产生...阻塞信号集也叫做当前进程的 信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略 注意:该类型只在 Linux 系统上有效,是 Linux 给用户提供的一个用户级的数据类型...SIG_SETMASK:将信号屏蔽字设置为 set 中的信号集,完全替换掉当前的屏蔽字。 2)set:指向一个 sigset_t 类型的信号集,表示需要操作的信号集合。...如果 oset 和 set 都是非空指针, 则先将原来的信号屏蔽字备份到 oset里,然后根据 set 和 how 参数更改信号屏蔽字。

    13410

    【Linux信号】四:SIGCHLD信号

    SIGCHLD产生的条件 实际上,在子进程结束的时候,会产生一个SIGCHLD信号,信号描述如下,根据man手册可以知道,子进程结束运行,其父进程会收到SIGCHLD信号,该信号的默认处理动作是忽略。...printf("recycle process: %d\n", pid); } } int main(void) { int i = 0; pid_t pid; /*先屏蔽...mact.sa_mask); mact.sa_handler = mcatch; sigaction(SIGCHLD, &mact, NULL); /*恢复原来的屏蔽设置...可能 产生僵尸进程,使用mcatch2会更好*/ } return 0; } 根据这个例子,我们可以得到下面几点注意事项 子进程继承了父进程的信号屏蔽字和信号处理动作...,分析慢速系统调用,慢速系统调用被中断的相关行为,实际上就是pause的行为,比 如read 慢速系统调用被中断的相关行为,实际上就是pause的行为,比 如read 想中断pause,首先信号不能被屏蔽

    17410

    Linux 信号

    signal 信号是 UNIX 系统最先开始使用的进程间通信机制,因为 Linux 是继承于 UNIX 的,所以 Linux 也支持信号机制,通过向一个或多个进程发送 异步事件信号 来实现,信号可以从键盘或者访问不存在的位置等地方产生...SIGBUS SIGBUS 将造成 总线中断 错误时发送给进程 SIGCHLD 当子进程终止、被中断或者被中断恢复,将 SIGCHLD 发送给进程。...SIGSTOP SIGSTOP 指示操作系统终止以便以后进行恢复时 SIGSYS 当 SIGSYS 信号将错误参数传递给系统调用时,该信号将发送到进程。...SYSTERM 我们上面简单提到过了 SYSTERM 这个名词,这个信号发送给进程以请求终止。与 SIGKILL 信号不同,该信号可以被过程捕获或忽略。...不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。 此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。

    4.8K20

    Linux信号

    (操作系统能识别到该行为,是因为当进程被切换时寄存器的数据也要被替换,因此状态寄存器要被恢复一次,在恢复的时候操作系统就能识别到状态寄存器的信息)。...---- 2.sigprocmask 调用sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集) #include int sigprocmask(int how,...如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。 如果oset和set都是非空指针,则先将原来的信号 屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。...假设当前的信号屏蔽字为mask,下表说明了how参数的可选值 : 如果调用sigprocmask函数解除了对某个未决信号的阻塞,那么再sigprocmask返回前,该信号可能已经被递达了,一旦信号递达...cout 恢复对信号的屏蔽,不屏蔽任何信号\n"; } } return 0; } 但是由于我对该信号做自定义捕捉了,所以2号信号无法终止该进程了。

    21130

    【Linux】————信号

    阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这里的“屏蔽”应该理解为阻塞而不是忽略。...如果oldset是非空指针,则读取进程的当前信号屏蔽字通过oldset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。...如果oldset和set都是非空指针,则先将原来的信号屏蔽字备份到oldset里,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值。...如果没有新的信号要递达,这次再返回用户态就是恢复main函数的上下文继续执行了。 信号捕捉的过程:要经历4次状态的切换。 在内核态切换回用户态的时候,进行信号的检测和处理。...sigaction sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0,出错则返回- 1。signum 是指定信号的编号。

    5910

    【Linux】信号

    今日更新了Linux信号的内容 欢迎大家关注点赞收藏⭐️留言 信号和信号量 二者之间没有任何关系。 信号 通过 kill -l 可以查看所有信号 其中,1-31号信号是普通信号。...进程要切换,就会把cpu里的寄存器值作保存和恢复。这意味着每次保存进程,就会把异常保存起来,因为进程不退,又会把异常恢复。所以OS就会一直触发错误,就会一直循环打印了。...sigaction sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0,出错则返回- 1。signum 是指定信号的编号。...因为当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来 的信号屏蔽字。...,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需 要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。

    7910

    【Linux】:进程信号(信号概念 & 信号处理 & 信号产生)

    温馨提示:信号和信号量 二者之间没有任何关系 1, 信号概念 信号是 Linux 系统提供的一种向指定进程发送特定事件的方式,进程会对信号进行识别和处理。...,Stop为进程暂停…… (Core终止进程同时还会形成一个debug文件,Term仅终止进程) 基本特点: 信号:Linux系统提供的一种,向指定进程发送特定事件的方式。...> #include int kill(pid_t pid, int sig); 参数分析: pid:指定进程pid,如果 pid 是负数,信号将被发送到与 pid...Linux是提供了定时功能的,定时器也要被管理:先描述,在组织。...上下文切换是一个相对耗时的过程,包括保存和恢复寄存器、堆栈等信息 当切换回这个进程的时候,溢出标志位的错误信息同样会被恢复,会频繁的导致除0异常而触发上下文切换,会大大增加系统的开销。

    9910

    Linux进程信号【信号产生】

    ---- 前言 在 Linux 中,进程具有独立性,进程在运行后可能 “放飞自我”,这是不利于管理的,于是需要一种约定俗成的方式来控制进程的运行,这就是 进程信号,本文将会从什么是进程信号开篇,讲述各种进程信号的产生方式及作用...,部分信号只做了解即可 1.2、信号的作用 早在 《Linux进程学习【进程状态】》 我们就已经使用过 信号 了,比如: kill -9 pid 终止进程运行 kill -19 pid 暂停进程运行 kill...-18 pid 恢复进程运行 就连常用的 ctrl+c 和 ctrl+d 热键本质上也是 信号 这么多信号,其对应功能是什么呢?...可以通过 man 7 signal 进行查询 man 7 signal 简单总结一下,1~31 号信号对应的功能如下(表格内容引用自 2021dragon Linux中的31个普通信号) 信号编号 信号名...构成,一个信号对应一种动作,对于进程来说,动作无非就这几种:终止进程、暂停进程、恢复进程,3 个信号就够用了啊,为什么要搞这么多信号?

    32010
    领券