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... ")
I need that when the variable text
is equal to "Close your program"
the 3 active processes(p1
,p2
,p3
) are closed.
I have tried to do something like this:
elif text.lower() == "Close your program":
print("the process has been interrupted!")
finish_state.set()
for process in [p1, p2, p3]:
process.terminate()
But it is not working for me, and I would need a better code that allows me to close them one by one in that code block if text
is equal to "Close your program"
.
What should I do so that under that condition all the processes are closed one by one?
CodePudding user response:
You could try the following Event-based solution (but there are even simpler solutions to follow):
Have main_process
pass to audio_listening
an additional argument, 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()
Note that it is now main_process
that is creating the finish_state
multiprocessing.Event
instance; there appears to be no need for it to be passed as an argument. When the event is set, the main process will terminate the subprocesses that it has created.
Then in 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
There are even two simpler alternatives that do not even require an Event
variable:
The audio_process
process is in an infinite loop until it either gets a "Close your program" message or it gets an exception. In both cases it terminates and presumably we then want the other two processes to terminate, also. Therefore, the main process can just issue a call to p2.join()
after it has started all the other processes in order to wait for the audio_process
process to complete and then either:
- Call
p1.terminate()
followed byp3.terminate()
. - Or start processes
p1
andp3
specifying daemon=True, e.g.p1 = multiprocessing.Process(target=capture_cam, args=(conn1, conn1b), daemon=True)
. Being daemon processes they will now automatically terminate as soon as the main process terminates. Therefore, there is no need to callterminate
on these processes.