在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似乎不适用于上述情况。

第页。S.:我正在学习Ubuntu 18.04。

编辑:经过大量调试,没有退出原来是因为我使用的库,我不怀疑会导致这种情况。我对虚惊一场表示歉意。感谢您就控制子进程的更好方式提出的建议。

您的程序对我有效,但让我插话"还有其他方法吗"。您可以创建一个共享事件对象,让子进程知道何时可以完成工作,而不是每隔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()

由于Python 3.7.7在FreeBSD 12.1(64位(上运行,我无法重现您的问题。

在修复了缩进并添加了必要的导入之后,更改后的程序运行良好的AFAICT。

顺便说一句,你可能想import sys并添加

sys.stdout.reconfigure(line_buffering=True)

main()的开始。

相关内容

最新更新