为什么 kill -INT 一些进程没有作用(比如后台启动并且启动 bash 已经退出的情况下)? 我是想让 python 程序得到 KeyboardInterrupt 体面地退出,可是一旦在后台了,就收不到 INT 信号了。

2014-08-26 09:44:59 +08:00
 love

比如:

$ (sleep 1h &)

这时sleep已经在后台运行,可是发INT给它杀不掉,这怎么破?

6681 次点击
所在节点    Linux
7 条回复
lu18887
2014-08-26 09:47:03 +08:00
kill -9 不行?
love
2014-08-26 09:49:20 +08:00
@lu18887
python写的程序在收到INT信号是会转成KeyboardInterrupt异常,这样退出比较好,可以做些清理,你kill -9就直接死掉了。
palxex
2014-08-26 11:44:13 +08:00
sleep(1)本身不处理SIGINT,你发给它当然没用了。写个python脚本自己实验一下就知道了,完全可以按你的预期工作。
tonyluj
2014-08-26 12:27:49 +08:00
1. SIGINT 可以被忽略,只有SIGKILL和SIGSTOP不能被忽略
2. 这与job control有关,你在shell下压入后台,后台进程组的默认handler是IGNORE
love
2014-08-26 12:50:12 +08:00
@palxex sleep可以处理INT,不信你在前台运行然后发个INT试试?python我试过不行才来问的。

@tonyluj 可是我没有在程序中忽略INT信号,同样的程序在前台可以收INT,跑去后台并且相关shell退出的情况下就收不到了。而在后台运行但shell没有退出时可以收INT。
love
2014-08-26 12:59:53 +08:00
我说的是这样:

```bash
[~]$ sleep 1h & # 在本地shell后台运行
[1] 5121
[~]$ kill -INT 5121 # kill成功
[1]+ Interrupt sleep 1h

[~]$ (sleep 1h &) # 在subshell后台运行,然后subshell自动退出
[~]$ ps
PID TTY TIME CMD
2623 pts/3 00:00:00 bash
5125 pts/3 00:00:00 sleep
5126 pts/3 00:00:00 ps
[~]$ kill -INT 5125 # 无效了!
[~]$ ps
PID TTY TIME CMD
2623 pts/3 00:00:00 bash
5125 pts/3 00:00:00 sleep
5127 pts/3 00:00:00 ps
[~]$
```
love
2014-08-26 13:54:21 +08:00
发现了一个方法绕过这个问题,只要在程序中捕获SIGTERM然后调用_thread.interrupt_main()就能转成KeyboardInterrupt异常了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/129906

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX