1
rogwan 2019-05-24 23:30:21 +08:00 via Android
你要知道进程 id 呀,主进程只负责起,不负责灭,他主进程不知道紫禁城什么时候干完活了啊。要控制的话,要进程间通讯才行
|
2
Abbeyok 2019-05-24 23:31:28 +08:00
不可能啊,主进程退出了,子进程也会强制退出啊。。
|
3
hakono 2019-05-24 23:34:50 +08:00
主进程退出的时候 Popen 调用 kill,( windows 的话 taskkill )手动杀了子进程
|
4
iyaozhen 2019-05-24 23:40:24 +08:00
一般都是父进程记录子进程的 pid,然后父进程退出时把子进程都 kill 一遍
|
5
Tink 2019-05-25 00:31:24 +08:00 via iPhone
subprocess 就是有这个问题,Popen 的时候把 pid 返回来保存,结束的时候直接杀掉
|
6
Qzier 2019-05-25 00:31:51 +08:00 via iPhone
proc = subprocess.Popen(...)
try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate() |
7
labnotok 2019-05-25 00:33:10 +08:00 via Android
手动 ps aux | grep xxx | awk '{print $2}' | kill 吧,
我前几天用 multiprocess 的 pool 的时候出了一堆 D 进程, D 进程只能手动关闭,父进程 加上 兄弟进程同时关,一般就能杀掉了 |
8
tangrwx 2019-05-25 08:52:00 +08:00 via iPhone
有个参数的可以开启进程组,好像是 pexec 或者 new_session。,你可以查下文档
|
9
hhhsuan 2019-05-25 10:54:14 +08:00
用 psutil,把子进程全 kill 了:
https://gist.github.com/xcjiang/bd19224a4b6cc79470118337cc3bdc8b |
10
lolizeppelin 2019-05-25 18:00:17 +08:00 1
这些其实都不是 python 的知识
好好把操作系统信号,和进程 fork 相关看一看 这些基础知识不熟悉,multiprocess、subprocess 各种问题你都不知道原因,各种标准的处理方法你都不知道 不熟悉的就不要瞎回答 比如上面有人说这种完全错误的话 ~~~ 不可能啊,主进程退出了,子进程也会强制退出啊。。 ~~ 强调一下!!!这些其实都不是 python 的问题!! |
11
lolizeppelin 2019-05-25 18:04:06 +08:00
上面的直接 kill 都不是正确做法
如果你子进程没处理信号的话,只能用信号 9,这种做法是非常不标准的 |
12
codehz 2019-05-25 21:23:41 +08:00
Linux 平台的话,可以用 prctl PR_SET_PDEATHSIG
|
13
PTLin 2019-05-25 22:23:11 +08:00
你可以用 atexit 注册个 exit handler,然后每次 fork 的时候记录下来,调用 handler 的时候向子进程发送 SIGTERM 信号,子进程也可以注册 signal handler 来进行退出的收尾工作。
|
14
wikinee OP |
15
wikinee OP |
16
tangrwx 2019-05-26 23:53:35 +08:00 via iPhone 1
@wikinee 试试 start_new_session 参数,其实本质是 Linux 进程组和会话的概念。
|
18
hakono 2019-05-27 01:03:31 +08:00
@wikinee 你担心主进程被强杀的话,那你可以改变策略在子进程里监视主进程啊,主进程退出的话就退出
如果子进程的程序不是你写的程序没法改代码加监视逻辑的话…… emmm …… 解决办法其实有……不过算有点骚操作,你可以往子进程里注入远程代码啊哈哈哈 在注入的代码里做主进程监视就行了,完美 |
19
lolizeppelin 2019-05-27 11:12:55 +08:00
不需要子进程监控主进程,有个很标准的做法是用管道
主进程 fork 前开管道 子进程开一个线程去读管道,后面紧跟强制退出代码 os._exit(1) 因为这个读取是阻塞的,当主进程挂掉的时候阻塞读能返回空,这样就知道主进程挂了 规范程序都按标准写法写的, 不懂把 openstack 的 luanch 那部分读透了就都明白了 |
20
PTLin 2019-05-27 12:18:30 +08:00
@wikinee 的确用 shell 实现也是很简单,cmd &放到后台,然后可以用 wait 来等待,不过我又想起来一个方法,进程 fork 后除非显式调用 setpgid 函数更改进程组 id 否则会继承父进程的进程组 id,这样父进程退出前用 kill 函数,pid 参数指定为 0 就可以发送给同一进程组的所有进程了。
|
21
butterfly1211 2019-05-27 15:48:27 +08:00
6 楼正解啊
|
22
mythmgn 2019-05-29 10:41:41 +08:00
楼主可以 wx 搜下我的号 程序员的梦呓指南 看下最近的 python 进程篇, 讲 os.system subprocess.Popen 家族裸用的原罪, 怎么处理子进程\孙子进程的问题
|
24
liuguichao 2019-05-30 15:05:30 +08:00
pgid = os.getpgid(self.proc.pid)
os.killpg(pgid, signal.SIGTERM) |