前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >刷题外传之如何优雅的杀掉进程

刷题外传之如何优雅的杀掉进程

作者头像
包子面试培训
发布2018-04-20 16:53:38
1.7K0
发布2018-04-20 16:53:38
举报
文章被收录于专栏:包子铺里聊IT包子铺里聊IT

进程(Process)是 Unix/Linux 系统下编程的核心知识。无论是小 Script 还是大 Daemon,启动后都是以进程的形势在 OS 中存在和执行。

进程的启动

启动进程其实最简单,假如我们有一段 Python Script (hello.py):

print “hello world”

运行它非常容易:

python hello.py

然后一个新的进程就产生了,由于代码很短,输出 “hello world” 之后进程就结束了。

启动进程的核心其实就是构建一个合法的命令行,通过 CLI / Process Controler 等方式调用它。程序的入口点只有一个,因此简洁、好调试。

进程的终结

重点来了,进程的终结相对复杂,来看看一些常见情况:

  • 程序运行很短(如上例),运行之后正常结束;
  • 程序运行时间长,小白用户烦了,Ctrl + C 硬关;
  • 程序运行时间长,程序员烦了,kill / pkill;
  • 程序运行时间长,一定要关死它(立即马上),kill -9

显然,关闭进程的方式多种多样,最理想的是,它正常结束。但生产环境中,你不能指望所有进程都顺顺利利,而且复杂一点的进程通常需要维护内部的数据状态,如果进程突然终止,但是内部维护的数据状态没有处理好,那就很糟糕了。

好吧,Ctrl + C 对于程序意味着什么呢?kill 和 kill -9 又有什么区别?

Signal

这就不得不说到 Signal.

Signal 是理解进程终止重要的概念,可以把它想象成一种 OS 内的消息,通常是在特殊的情况下由 OS 发给运行的 Program. 其实大家在写程序的时候已经用过它,比如你的程序 segement fault 了(悲催),其实 OS 就是发送了 “SIGSEGV” Signal 到你的程序然后 crash.

Signal 有很多,去 Wiki 一下,好像60多种,一般除非你要做 System Admin, 没必要全知道。但是最常见的几个要记住,很有用。

也许你猜到了,无论是 Ctrl + C, kill 还是 kill -9,其实都是由用户主动的发出 Signal 给一个特定的 Process.

  • Ctrl + C -> SIGINT
  • kill -> SIGTERM
  • kill -9 -> SIGKILL

这三个 Signal 一定要掌握。嗯,它们的区别呢?

Handle Signal

当你的程序收到 Signal 的时候,是不是一定就要退出呢?当然不是。

可能大家都有那种 ”按了一百遍 Ctrl + C, 程序就是关不掉,算你狠我还是重启吧“ 的情况,因为你的程序是可以 Handle Signal 的,看一段程序 (hello2.py):

import signal, time, sys def handle_signal(sign_num, frame): print “You pressed Ctrl + C” sys.exit(1) signal.signal(signal.SIGINT, handle_signal) for i in range(10000): print i time.sleep(1)

启动程序 python hello2.py 之后,它每一秒会打印一个新的数字。特别的是,我们给这个程序注册了一个 Handler SIGINT 的函数 (signal.signal(X, X) )

结果就是,在程序运行时,如果我们按 Ctrl + C, 那么 handle_signal 就会被执行,打印 “You pressed Ctrl + C”,然后退出。

如果你删掉 sys.exit(1) 这一行,那么 Ctrl + C 也没法干掉它了。

类似的,如果你为 SIGTERM 也注册一个 Handler 函数,当 Kill 发生的时候,同样可以执行 Handler 里面的代码。

对于 SIGINT & SIGTERM, 如果程序没有注册处理信号的方法,那么默认的行为是结束进程。

SIGKILL 是一个例外(From Kill -9),这个信号是程序内部无法 Catch & Handle 的,它的意思很明确:发给你,别废话,直接结束。

Handle Signal 的好处

前文提到过,复杂一点的程序都有很多的 State 需要维护,比如和数据库记录,文件的记录等等。Signal Handler 给了我们 cleanup 状态的机会。比如程序和数据库打交道,如果中途被 SIGITN 或者 SIGTERM,可以做点 logging (记录下为什么要结束),然后 mark job/state as failure 之类。别小看这些 cleanup function, 能处理好 edge cases 的程序才称得上健壮。

由于 SIGKILL 的特殊性,一旦执行,程序即使有 cleanup 也不能执行,因此请小心使用,千万不要图快什么都 Kill -9.

待续

本文只讨论一个进程的例子,但是大量的 Unix/Linux 进程(Process)在运行中会 Fork/Exec 新的进程。换句话说,一个结点的问题变成了一颗树的问题,那么信号如何传递,信号如何处理,下一篇文章我们继续讨论。

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

本文分享自 包子铺里聊IT 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 进程的启动
  • 进程的终结
    • Signal
      • Handle Signal
        • Handle Signal 的好处
        • 待续
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档