首页 > 解决方案 > 在 Python 中控制子进程流的最佳方法是什么?

问题描述

我正在尝试从父进程运行、暂停和终止 Python 中的子进程。我曾尝试使用,但由于某种原因,尽管我和所有进程都multiprocessing.Value没有完全完成父进程。我的用例是这样的:terminatejoin

def child(flow_flag):
   while True:
      with flow_flag.get_lock():
          flag_value = flow_flag.value
      if flag_value == 0:
         print("This is doing some work")
      elif flag_value == 1:
         print("This is waiting for some time to check back later")
         time.sleep(5)
      else:
         print("Time to exit")
         break

def main():
    flow_flag = Value('i', 0)
    processes  = [Process(target=child, args=(flow_flag,)) for i in range(10)]
    [p.start() for p in processes]    
    print("Waiting for some work")
    with flow_flag.get_lock():    
        flow_flag.value = 1
    print("Do something else")
    with flow_flag.get_lock():    
        flow_flag.value = 0
    print("Waiting for more work")
    with flow_flag.get_lock():    
        flow_flag.value = 2
    print("Exiting")
    for p in processes:
        p.terminate()
        p.join()

这永远不会正确完成,我Ctrl+C最终必须这样做。然后我看到这条消息:

Traceback (most recent call last):
  File "/home/abcde/anaconda3/lib/python3.7/threading.py", line 1308, in _shutdown
    lock.acquire()
KeyboardInterrupt

有什么更好的方法?仅供参考,在等待其他东西的同时,我正在产生一些其他进程。我也让它们没有正确终止,我也Value和它们一起使用。当我切换到Queue为他们使用时,它得到了修复。但是,Queue似乎不适用于上述情况。

PS:我正在进入 Ubuntu 18.04。

编辑:经过大量调试,没有退出原来是因为我正在使用的一个库,我没有怀疑会导致这种情况。对于误报,我深表歉意。感谢您提供有关控制子进程的更好方法的建议。

标签: pythonmultiprocessingpython-multiprocessing

解决方案


你的程序对我有用,但让我插话“还有其他方法吗”。您可以创建一个共享事件对象,而不是每隔 5 秒轮询一次,让子进程知道他们何时可以完成工作。不要轮询值 1,而是等待事件。

from multiprocessing import *
import time
import os

def child(event, times_up):
    while True:
        event.wait()
        if times_up.value:
            print(os.getpid(), "time to exit")
            return
        print(os.getpid(), "doing work")
        time.sleep(.5)

def main():
    manager = Manager()
    event = manager.Event()
    times_up = manager.Value(bool, False)
    processes  = [Process(target=child, args=(event, times_up)) for i in range(10)]
    [p.start() for p in processes]
    print("Let processes work")
    event.set()
    time.sleep(2)
    print("Make them stop")
    event.clear()
    time.sleep(4)
    print("Make them go away")
    times_up.value = True
    event.set()
    print("Exiting")
    for p in processes:
        p.join()

if __name__ == "__main__":
    main()

推荐阅读