python学习笔记10.4 通过killpg杀死进程组

在实际使用多进程的过程中,希望一个子进程报错,则停止所有进程,并退出主进程。在子进程中不能使用exit()函数,它会使得主进程一直等待,程序就卡在这里了。

from  multiprocessing import Pool
import time
import os
import sys
import signal
import subprocess
import platform
def f(i):
    print(f'running {i}, pid: {os.getgid()}')
    if i == 3:
        time.sleep(5)
        print('exit in subp')
        exit()
    time.sleep(3)
    return i

def call_back(i):
    print('callback:',i)

def error_call_back(i):
    print('error:',i)
    
def main():
    mp = Pool(4)
    for i in range(10):
        mp.apply_async(f,args=(i,),callback=call_back,error_callback=error_call_back)
    mp.close()
    mp.join()
if __name__ == '__main__':
    main()

程序运行:

running 0, pid: 1000
running 1, pid: 1000
running 2, pid: 1000
running 3, pid: 1000
callback: 0
running 4, pid: 1000
callback: 1
running 5, pid: 1000
callback: 2
running 6, pid: 1000
exit in subp
None
running 7, pid: 1000
callback: 4
running 8, pid: 1000
callback: 5
running 9, pid: 1000
callback: 6
callback: 7
callback: 8
callback: 9

程序并不会退出。

解决方案:使用在error_callback中使用killpg函数,杀死进程组。

from  multiprocessing import Pool
import time
import os
import sys
import signal
import subprocess
import platform
def f(i):
    print(f'running {i}, pid: {os.getgid()}')
    
    if i == 3:
        time.sleep(5)
        print('subprocess raise error, jump to error callback')
        raise ValueError(f'error in {i}')
    time.sleep(3)
    return i

def call_back(i):
    print('callback:',i)

def error_call_back(i):
    print('error:',i)
    print('exit by killpg')
    kill_sig = signal.SIGKILL
    os_name = platform.system()
    if os_name == 'Windows':
        kill_sig = signal.CTRL_C_EVENT
    os.killpg(os.getpgid(os.getpid()), kill_sig)
    
def main():
    mp = Pool(4)
    for i in range(10):
        mp.apply_async(f,args=(i,),callback=call_back,error_callback=error_call_back)
    mp.close()
    mp.join()
if __name__ == '__main__':
    main()

运行结果:

running 0, pid: 1000
running 1, pid: 1000
running 2, pid: 1000
running 3, pid: 1000
callback: 0
running 4, pid: 1000
callback: 1
running 5, pid: 1000
callback: 2
running 6, pid: 1000
subprocess raise error, jump to error callback
running 7, pid: 1000
error: error in 3
exit by killpg

这样就能解决两个问题:
(1)子进程发生异常时所有子进程退出且主进程退出。
(2)子进程中不能使用exit()函数问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值