如何通过在其中一个进程中找到的 'if' 验证在使用多处理操作的程序中一个接一个地关闭所有进程?
How to close all the processes one by one in a program that operates with multiprocessing by means of an 'if' validation found in one of them process?
import multiprocessing
from threading import Thread
import speech_recognition as sr
def actions_func(conn1_3,conn2_3):
def capture_cam(conn1, conn1b):
def audio_listening(conn2, conn2b):
global catch_current_frame
catch_current_frame = False
# start dameon thread to handle frame requests:
Thread(target=handle_catch_current_frame_requests, args=(conn2,), daemon=True).start()
Thread(target=handle_cam_activate_requests, args=(conn2b,), daemon=True).start()
while True:
r = sr.Recognizer()
with sr.Microphone() as source:
catch_current_frame = False
r.adjust_for_ambient_noise(source)
print("Please say something...")
audio = r.listen(source)
try:
text = r.recognize_google(audio, language="es-ES")
print("You have said: \n " + repr(text))
#Verifications
if text.lower() == "capture":
catch_current_frame = True
elif text.lower() == "Close your program":
#This is where I need to close processes p1, p2 and p3
break
else:
pass
except Exception as e:
print("Error : " + str(e))
def main_process(finish_state):
conn1, conn1_3 = multiprocessing.Pipe(duplex=True)
conn2, conn2_3 = multiprocessing.Pipe(duplex=True)
conn1b, conn2b = multiprocessing.Pipe(duplex=True)
#Process 1
p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b, ))
p1.start()
#Process 2
p2 = multiprocessing.Process(target=audio_listening, args=(conn2, conn2b, ))
p2.start()
#Process 3
p3 = multiprocessing.Process(target=actions_func, args=(conn1_3 ,conn2_3 ,))
p3.start()
if __name__ == '__main__':
finish_state = multiprocessing.Event()
main_process(finish_state)
print("continue the code... ")
我需要当变量 text
等于 "Close your program"
时关闭 3 个活动进程(p1
、p2
、p3
)。
我试过这样做:
elif text.lower() == "Close your program":
print("the process has been interrupted!")
finish_state.set()
for process in [p1, p2, p3]:
process.terminate()
但它对我不起作用,如果 text
等于 "Close your program"
,我需要一个更好的代码,允许我在该代码块中一个一个地关闭它们。
在这种情况下,我应该怎么做才能将所有进程都一一关闭?
您可以尝试以下Event-based解决方案(但还有更简单的解决方案可供遵循):
让 main_process
传递给 audio_listening
一个额外的参数,finish_state
:
def main_process():
conn1, conn1_3 = multiprocessing.Pipe(duplex=True)
conn2, conn2_3 = multiprocessing.Pipe(duplex=True)
conn1b, conn2b = multiprocessing.Pipe(duplex=True)
#Process 1
p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b, ))
p1.start()
#Process 2
finish_state = multiprocessing.Event()
p2 = multiprocessing.Process(target=audio_listening, args=(conn2, conn2b, finish_state))
p2.start()
#Process 3
p3 = multiprocessing.Process(target=actions_func, args=(conn1_3 ,conn2_3 ,))
p3.start()
finish_state.wait()
p1.terminate()
p2.terminate() # Not really necessary since the process is ending by itself
p3.terminate()
if __name__ == '__main__':
main_process()
请注意,现在 main_process
正在创建 finish_state
multiprocessing.Event
实例;似乎没有必要将其作为参数传递。设置事件后,主进程将终止它创建的子进程。
然后在audio_processing:
def audio_listening(conn2, conn2b, finish_state):
...
if text.lower() == "capture":
catch_current_frame = True
elif text.lower() == "Close your program":
# Set the finish state event:
finish_state.set()
break
甚至还有两个甚至不需要 Event
变量的更简单的替代方案:
audio_process
进程处于无限循环中,直到它收到“关闭您的程序”消息或收到异常。在这两种情况下,它都会终止,然后我们可能希望其他两个进程也终止。因此,主进程可以在启动所有其他进程后调用 p2.join()
以等待 audio_process
进程完成,然后:
- 调用
p1.terminate()
,然后调用 p3.terminate()
。
- 或者启动进程
p1
和 p3
指定 daemon=True,例如p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b), daemon=True)
。作为守护进程,它们现在将在主进程终止后立即自动终止。因此,不需要在这些进程上调用 terminate
。
import multiprocessing
from threading import Thread
import speech_recognition as sr
def actions_func(conn1_3,conn2_3):
def capture_cam(conn1, conn1b):
def audio_listening(conn2, conn2b):
global catch_current_frame
catch_current_frame = False
# start dameon thread to handle frame requests:
Thread(target=handle_catch_current_frame_requests, args=(conn2,), daemon=True).start()
Thread(target=handle_cam_activate_requests, args=(conn2b,), daemon=True).start()
while True:
r = sr.Recognizer()
with sr.Microphone() as source:
catch_current_frame = False
r.adjust_for_ambient_noise(source)
print("Please say something...")
audio = r.listen(source)
try:
text = r.recognize_google(audio, language="es-ES")
print("You have said: \n " + repr(text))
#Verifications
if text.lower() == "capture":
catch_current_frame = True
elif text.lower() == "Close your program":
#This is where I need to close processes p1, p2 and p3
break
else:
pass
except Exception as e:
print("Error : " + str(e))
def main_process(finish_state):
conn1, conn1_3 = multiprocessing.Pipe(duplex=True)
conn2, conn2_3 = multiprocessing.Pipe(duplex=True)
conn1b, conn2b = multiprocessing.Pipe(duplex=True)
#Process 1
p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b, ))
p1.start()
#Process 2
p2 = multiprocessing.Process(target=audio_listening, args=(conn2, conn2b, ))
p2.start()
#Process 3
p3 = multiprocessing.Process(target=actions_func, args=(conn1_3 ,conn2_3 ,))
p3.start()
if __name__ == '__main__':
finish_state = multiprocessing.Event()
main_process(finish_state)
print("continue the code... ")
我需要当变量 text
等于 "Close your program"
时关闭 3 个活动进程(p1
、p2
、p3
)。
我试过这样做:
elif text.lower() == "Close your program":
print("the process has been interrupted!")
finish_state.set()
for process in [p1, p2, p3]:
process.terminate()
但它对我不起作用,如果 text
等于 "Close your program"
,我需要一个更好的代码,允许我在该代码块中一个一个地关闭它们。
在这种情况下,我应该怎么做才能将所有进程都一一关闭?
您可以尝试以下Event-based解决方案(但还有更简单的解决方案可供遵循):
让 main_process
传递给 audio_listening
一个额外的参数,finish_state
:
def main_process():
conn1, conn1_3 = multiprocessing.Pipe(duplex=True)
conn2, conn2_3 = multiprocessing.Pipe(duplex=True)
conn1b, conn2b = multiprocessing.Pipe(duplex=True)
#Process 1
p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b, ))
p1.start()
#Process 2
finish_state = multiprocessing.Event()
p2 = multiprocessing.Process(target=audio_listening, args=(conn2, conn2b, finish_state))
p2.start()
#Process 3
p3 = multiprocessing.Process(target=actions_func, args=(conn1_3 ,conn2_3 ,))
p3.start()
finish_state.wait()
p1.terminate()
p2.terminate() # Not really necessary since the process is ending by itself
p3.terminate()
if __name__ == '__main__':
main_process()
请注意,现在 main_process
正在创建 finish_state
multiprocessing.Event
实例;似乎没有必要将其作为参数传递。设置事件后,主进程将终止它创建的子进程。
然后在audio_processing:
def audio_listening(conn2, conn2b, finish_state):
...
if text.lower() == "capture":
catch_current_frame = True
elif text.lower() == "Close your program":
# Set the finish state event:
finish_state.set()
break
甚至还有两个甚至不需要 Event
变量的更简单的替代方案:
audio_process
进程处于无限循环中,直到它收到“关闭您的程序”消息或收到异常。在这两种情况下,它都会终止,然后我们可能希望其他两个进程也终止。因此,主进程可以在启动所有其他进程后调用 p2.join()
以等待 audio_process
进程完成,然后:
- 调用
p1.terminate()
,然后调用p3.terminate()
。 - 或者启动进程
p1
和p3
指定 daemon=True,例如p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b), daemon=True)
。作为守护进程,它们现在将在主进程终止后立即自动终止。因此,不需要在这些进程上调用terminate
。