前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >unix进程间通信信号的有效实践

unix进程间通信信号的有效实践

作者头像
有态度的马甲
发布于 2025-04-07 06:15:04
发布于 2025-04-07 06:15:04
3800
代码可运行
举报
文章被收录于专栏:精益码农精益码农
运行总次数:0
代码可运行

背景

最近优化了一版程序:用到了golang的优雅退出机制。

程序使用leader/follower分布式高可用模型,所有的请求都会命中leader;

使用etcd的election sdk做选主,需要在节点意外下线的时候,主动去etcd卸任(删除10s租约), 否则已经下线的节点还会被etcd认为是leader。

所以在这里,优雅退出是技术刚需。

另外根据[云原生十二要素方法论] 第9条: 快速启动和优雅终止可最大化健壮性 , 也推荐各位遵守实践。 Fast startup and shutdown are advocated for a more robust and resilient system.


粗浅的认知方案:捕获程序的终止信号, 主动去卸任。

1. 进程间通信信号

进程间通信信号是操作系统提供的信号机制的内容, 它不是我们开发者长陷入其中的网络或者Socket通信

kill -l 命令可以列出系统支持的所有进程间通信信号, 下面粗体是常见的、可能用到的通信信号

  • SIGHUP (1) : 挂起信号,通常用于在终端断开时通知进程,也用于通知进程重新加载配置文件。
  • SIGINT (2) : 中断信号,通常由用户通过 Ctrl+C 组合键发送,用于中断一个进程。
  • SIGQUIT (3) : 退出信号,通常由用户通过 Ctrl+\ 组合键发送,用于退出一个进程,并生成核心转储。
  • SIGILL (4) : 非法指令信号,表示进程试图执行非法指令。
  • SIGABRT (6) : 中止信号,通常由调用 abort() 函数产生,用于异常终止一个进程。
  • SIGFPE (8) : 浮点异常信号,表示进程发生算术错误,如除以零。
  • SIGKILL (9) : 杀死信号,强制终止进程,无法被捕获或忽略。
  • SIGSEGV (11) : 段错误信号,表示进程试图访问未分配的内存。
  • SIGPIPE (13) : 管道破裂信号,表示进程写入一个没有读取端的管道。
  • SIGALRM (14) : 定时器信号,由 alarm() 函数产生,用于定时通知进程。
  • SIGTERM (15) : 终止信号,通常用于请求进程优雅地终止。
  • SIGUSR1 (10) 和 SIGUSR2 (12) : 用户自定义信号,供用户和应用程序自行定义用途。
  • SIGCHLD (17) : 子进程状态改变信号,当子进程终止或停止时,父进程会收到此信号。
  • SIGCONT (18) : 继续执行信号,用于恢复暂停的进程。
  • SIGSTOP (19) : 暂停信号,停止进程的执行,无法被捕获或忽略。
  • SIGTSTP (20) : 终端停止信号,通常由用户通过 Ctrl+Z 组合键发送,用于暂停进程。
  • SIGTTIN (21) 和 SIGTTOU (22) : 后台进程试图从终端读取或写入数据时发送的信号。

2. Go应用侦听SIGINT、SIGTERM信号实现优雅退出

有进程终止效果的常用信号有三个:SIGINT、 SIGKILL、SIGTERM, 其中SIGKILL(kill -9) 无法被应用捕获或忽略。

一般应用捕获SIGINT(interrupt中断)、SIGTERM(terminate终止)信号就可在终止之前注入行为。

golang提供signal包来监听收到的进程间通信信号。

针对长时间运行的程序,新开协程,持续监听信号,并插入优雅关闭的代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    c := make(chan os.Signal)
    signal.Notify(c, syscall.SIGTERM, syscall.SIGINT)
    go func() {
      select  {
       case sig:= <-c: {
        log.Infof("Got %s signal. Aborting...\n", sig)
        eCli.Close()    // 利用 etcd election sdk主动卸任
        os.Exit(1)    
       }
      }
     }()

3. 利用SIGSTOP信号模拟进程阻塞

SIGSTOP:暂停进程, 这意味着进程挂起,直到收到SIGCONT信号(continue)才能继续运行。

Q: 进程暂停是什么状态?

1> .收到SIGSTOP信号, 进程会停止运行, 不会执行任何代码,直到被显式恢复; 2>. 不可忽略,这意味着进程收到信号,无法自行决定如何响应,操作系统会直接暂停它; 3>. 资源保持, 虽然被暂停,但依然保留所有系统资源(内存、文件描述符), 这不像进程终止,会释放所有资源。

client===> A===>B, 模拟进程B阻塞:

1>. 对进程B执行kill -STOP {pid}  暂停进程

2>. time curl  192.168.8.88/test/timeoutAPI 输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 0.01s user 0.01s system 0% cpu 10.168 total
// 这意味着进程A请求B的超时时间是10s

4. Nginx使用SIGHUP信号实现热更新

上面的STOP信号是纯正的暂停信号,进程无法拒绝

HangUp信号最初用于终端断开时通知应用进程, 默认行为是终止进程;

由于HUP信号可被应用捕获,在现代应用中,HUP信号常用于通知守护进程重新加载其配置文件。

Nginx master进程重写了HUP信号默认终止进程的逻辑,自定义了处理逻辑,实现了配置的热更新。

btw, 在机器与内master进程直接交互, 不是特别便利;

nginx  0.8版本之后,给出了一系列命令行参数, nginx -s reload这个命令会启动一个nginx前台进程,自动定位master进程,向master进程发送HUP信号。

相关资料:https://tengine.taobao.org/book/chapter_02.html#id1

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 精益码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux 进程信号的基本概念、信号类型、信号处理方式、信号传递机制以及如何使用进程信号进行进程间通信、异常处理
进程信号是在操作系统中用于进程间通信和控制的一种机制。当一个进程接收到一个信号时,操作系统会做出相应的处理,例如终止进程、暂停进程等。在 Linux 中,进程信号被广泛应用于多种场景,例如进程间通信、异常处理、线程同步等。本文将详细介绍 Linux 进程信号的基本概念、信号类型、信号处理方式、信号传递机制以及如何使用进程信号进行进程间通信、异常处理等。
网络技术联盟站
2023/06/04
1.6K0
Linux 信号(Signal)
我们经常会使用 kill 命令杀掉运行中的进程,对多次杀不死的进程进一步用 kill -9 干掉它。你可能知道这是在用 kill 命令向进程发送信号,优雅或粗暴的让进程退出。我们能向进程发送很多类型的信号,其中一些常见的信号 SIGINT 、SIGQUIT、 SIGTERM 和 SIGKILL 都是通知进程退出,但它们有什么区别呢?很多人经常把它们搞混,这篇文章会让你了解 Linux 的信号机制,以及一些常见信号的作用。
mazhen
2023/11/24
1.3K0
Linux 信号(Signal)
Linux进程间通信(三) - 信号
什么是信号 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。 收到信号的进程对各种信号有不同的
三丰SanFeng
2018/01/16
2.6K0
Linux 信号
Linux进程间通信(Inter-Process communication, IPC)机制通常分6种:
Laikee
2022/04/25
4.9K0
Linux 信号
L007Linux信号、信号处理和信号处理函数
信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式。在Linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某种程序发生了什么事件,还可以给进程传递数据。
上善若水.夏
2018/09/28
4.2K0
python 进程间通信(一) -- 信号的基本使用
上一篇文章中,我们看到了如何通过 multiprocessing 来创建子进程。 通过 multiprocessing 实现 python 多进程
用户3147702
2022/06/27
1.7K0
python 进程间通信(一) -- 信号的基本使用
UNIX和Linux信号
1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。
一见
2018/08/07
4.2K0
kill命令
kill命令向指定的pid进程发送信号,如果不指定要发送的signal信号,则默认情况下signal是SIGTERM,它会终止进程,要列出所有可用信号,可以使用-l选项获取Linux信号列表,经常使用的信号包括HUP、INT、KILL、STOP、CONT和0,可以通过三种方式指定信号: 按数字例如-9,带有SIG前缀例如-SIGKILL,不带SIG前缀例如-KILL。负PID值用于指示过程组ID,如果传递了进程组ID,则该组中的所有进程都将接收到该信号,PID为-1是特殊的,其指示除两个以外的所有进程,kill进程本身和init即PID 1,其是系统上所有进程的父进程,将-1指定为目标会将信号发送到除这两个以外的所有进程。
WindRunnerMax
2021/02/25
1.4K0
GO的优雅终止姿势
程序使用etcd的election sdk做高可用选主,需要在节点意外下线的时候,主动去etcd卸任(删除10s租约), 否则已经下线的节点还会被etcd认为是leader。
有态度的马甲
2022/03/30
6950
【Linux探索学习】第二十七弹——信号(一):Linux 信号基础详解
https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482
GG Bond1
2025/02/02
1460
【Linux探索学习】第二十七弹——信号(一):Linux 信号基础详解
Linux信号列表及其详解
列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。
zy010101
2019/05/25
14.6K0
【操作系统】进程间的通信——信号
​ SIGABORT—— 进程异常终止 ​ SIGALRM ——超时告警 ​ SIGFPE —— 浮点运算异常 ​ SIGHUP ——连接挂断 ​ SIGILL——非法指令 ​ SIGINT ——终端中断 (Ctrl+C将产生该信号) ​ SIGKILL ——*终止进程 ​ SIGPIPE ——向没有读进程的管道写数据 ​ SIGQUIT——终端退出(Ctrl+\将产生该信号) ​ SIGSEGV ——无效内存段访问 ​ SIGTERM ——终止 ​ SIGUSR1——*用户自定义信号1 ​ SIGUSR2 ——*用户自定义信号2 ​ -------------------------------------->以上信号如果不被捕获,则进程接受到后都会终止! ​ SIGCHLD——子进程已停止或退出 ​ SIGCONT ——*让暂停的进程继续执行 ​ SIGSTOP ——*停止执行(即“暂停") ​ SIGTSTP——断挂起 ​ SIGTTIN —— 后台进程尝试读操作 ​ SIGTTOU——后台进程尝试写
半生瓜的blog
2023/05/13
5340
【操作系统】进程间的通信——信号
kill(1) command
kill 命令可以发送指定的信号到相应的进程或进程组。不指定信号缺省发送 SIGTERM(15)来终止指定进程。如果想强制终止进程,可以显示指定 SIGKILL(9) 信号,因为该信号无法被进程捕获。
恋喵大鲤鱼
2023/10/12
2560
Golang信号处理和如何实现进程的优雅退出
各操作系统的信号定义或许有些不同。下面列出了POSIX中定义的信号。 在linux中使用34-64信号用作实时系统中。 命令 man 7 signal 提供了官方的信号介绍。也可以是用kill -l来快速查看 列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。 Linux支持的标准信号有以下一些,一个信号有多个值的是因为不同架构使用的值不一样,比如x86, ia64,ppc, s390, 有3个值的,第一个值是slpha和sparc,中间的值是 ix86, ia64, ppc, s390, arm和sh, 最后一个值是对mips的,连字符-表示这个架构是缺这个信号支持的, 第1列为信号名; 第2列为对应的信号值,需要注意的是,有些信号名对应着3个信号值,这是因为这些信号值与平台相关,将man手册中对3个信号值的说明摘出如下,the first one is usually valid for alpha and sparc, the middle one for i386, ppc and sh, and the last one for mips. 第3列为操作系统收到信号后的动作,Term表明默认动作为终止进程,Ign表明默认动作为忽略该信号,Core表明默认动作为终止进程同时输出core dump,Stop表明默认动作为停止进程。 第4列为对信号作用的注释性说明。
黑光技术
2019/03/06
2.9K0
php进程通信-进程信号
快一个月没发博文了,之前都在深入研究php多进程tcp服务器,结果到现在也没搞出一个完美的解决方案,所以还是先发下这个月学到的东西吧
仙士可
2019/12/18
1.5K0
linux | kill命令详解以及linux中的信号
在man手册中对kill命令的解释如下, 不难看出, kill命令是一个用于将指定的signal发送给进程的工具
Amadeus
2023/04/12
2.7K0
异步通信之 信号
在软件层次上对中断机制的一种模拟,是一种异步通信的方式 。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。
看、未来
2021/10/09
1.2K0
异步通信之 信号
PHP进程间通信-信号
(一)PHP进程间通信-信号 信号是一种系统调用。通常我们用的kill命令就是发送某个信号给某个进程的。具体有哪些信号可以在liunx/mac中运行kill -l查看。下面这个例子中,父进程等待5秒钟,向子进程发送sigint信号。子进程捕获信号,调信号处理函数处理。
码农编程进阶笔记
2021/07/20
1.8K0
sigterm信号_一文吃透 PHP 进程信号处理
前两周老大给安排了一个任务,写一个监听信号的包。因为我司的项目是运行在容器里边的,每次上线,需要重新打包镜像,然后启动。在重新打包之前,Dokcer会先给容器发送一个信号,然后等待一段超时时间(默认10s)后,再发送SIGKILL信号来终止容器
全栈程序员站长
2022/11/01
1.2K0
sigterm信号_一文吃透 PHP 进程信号处理
[golang]golang signal.Notify 信号,如何优雅的退出
Notify函数让signal包将输入信号转发到c。如果没有列出要传递的信号,会将所有输入信号传递到c;否则只传递列出的输入信号。
landv
2020/06/16
18.5K1
相关推荐
Linux 进程信号的基本概念、信号类型、信号处理方式、信号传递机制以及如何使用进程信号进行进程间通信、异常处理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档