Terminate a Python multiprocessing program once a one of its workers meets a certain condition

后端 未结 4 1595
一向
一向 2020-12-05 03:32

I am writing a Python program using its multiprocessing module. The program calls a number of worker functions, each yielding a random number. I need to terminate th

4条回答
  •  囚心锁ツ
    2020-12-05 03:56

    As one of the other users mentioned, you need the processes to communicate with each other in order to get them to terminate their peers. While you can use os.kill to terminate the peer processes, it is more graceful to signal a termination.

    The solution I used is a pretty simple one: 1. find out the process ID (pid) of the main process, which spawns all the other worker processes. This connection information is available from the OS, which keeps track which child process was spawned from which parent process. 2. when one of the worker processes reaches your end condition, it uses the parent process ID to find all the child processes of the main process (including itself), then goes through the list and signals them to end (making sure it is not signaling itself) The code below contains the working solution.

    import time
    import numpy as np
    import multiprocessing as mp
    import time
    import sys
    import os
    import psutil
    import signal
    
    pid_array = []
    
    def f(i):
        np.random.seed(int(time.time()+i))
    
        time.sleep(3)
        res=np.random.rand()
        current_process = os.getpid()
        print "From i = ",i, "       res = ",res, " with process ID (pid) = ", current_process
        if res>0.7:
            print "find it"
            # solution: use the parent child connection between processes
            parent = psutil.Process(main_process)
            children = parent.children(recursive=True)
            for process in children:
                if not (process.pid == current_process):
                    print "Process: ",current_process,  " killed process: ", process.pid
                    process.send_signal(signal.SIGTERM)
    
    
    if __name__=='__main__':
        num_workers=mp.cpu_count()
        pool=mp.Pool(num_workers)
        main_process = os.getpid()
        print "Main process: ", main_process
        for i in range(num_workers):
            p=mp.Process(target=f,args=(i,))
            p.start()
    

    The output gives a clear idea of what is happening:

    Main process:  30249
    From i =  0        res =  0.224609517693  with process ID (pid) =  30259
    From i =  1        res =  0.470935062176  with process ID (pid) =  30260
    From i =  2        res =  0.493680214732  with process ID (pid) =  30261
    From i =  3        res =  0.342349294134  with process ID (pid) =  30262
    From i =  4        res =  0.149124648092  with process ID (pid) =  30263
    From i =  5        res =  0.0134122107375  with process ID (pid) =  30264
    From i =  6        res =  0.719062852901  with process ID (pid) =  30265
    find it
    From i =  7        res =  0.663682945388  with process ID (pid) =  30266
    Process:  30265  killed process:  30259
    Process:  30265  killed process:  30260
    Process:  30265  killed process:  30261
    Process:  30265  killed process:  30262
    Process:  30265  killed process:  30263
    Process:  30265  killed process:  30264
    Process:  30265  killed process:  30266
    

提交回复
热议问题