I think I need some suggestion here. Below is my code:
from multiprocessing import Pool
import time
import sys
def testing(number):
count = 0
while True:
print('Count: {}'.format(count))
count += 1
if count > number:
print('Exiting...')
sys.exit()
else:
print('Looping Over')
time.sleep(1)
if __name__ == '__main__':
with Pool(2) as p:
p.map(testing, [3, 2])
EXPECTED OUTCOME:
The program (main thread) should exit once all child threads have exited.
ACTUAL RESULT:
$ python3 test_exit.py
Count: 0
Looping Over
Count: 0
Looping Over
Count: 1
Looping Over
Count: 1
Looping Over
Count: 2
Looping Over
Count: 2
Exiting... <<< Exited 1st thread.
Count: 3
Exiting... <<< Exited 2nd thread.
....and it stays here as if stuck or something. It never gives control back to Shell.
EXPECTED RESULT:
$ python3 test_exit.py
Count: 0
Looping Over
Count: 0
Looping Over
Count: 1
Looping Over
Count: 1
Looping Over
Count: 2
Looping Over
Count: 2
Exiting...
Count: 3
Exiting...
$ <<< Note: I am expecting to be dropped back to Shell prompt
QUESTION:
Is there something wrong in my approach in term of pool/map usage?
We can kill or terminate a process immediately by using the terminate() method. We will use this method to terminate the child process, which has been created with the help of function, immediately before completing its execution.
The Pool class in multiprocessing can handle an enormous number of processes. It allows you to run multiple jobs per process (due to its ability to queue the jobs). The memory is allocated only to the executing processes, unlike the Process class, which allocates memory to all the processes.
As we have seen, the Process allocates all the tasks in memory and Pool allocates only executing processes in memory, so when the task numbers is large, we can use Pool and when the task number is small, we can use Process class.
sys.exit([arg]) Unlike quit() and exit() , sys. exit() is considered good to be used in production code for the sys module is always available. The optional argument arg can be an integer giving the exit or another type of object. If it is an integer, zero is considered “successful termination”.
The program (main thread) should exit once all child threads have exited.
testing()
(done through break
statement in the crucial loop)from multiprocessing import Pool, current_process
import time
import sys
def testing(number):
count = 0
while True:
print('Count: {}'.format(count))
count += 1
if count > number:
print('Exiting...', current_process().name)
break
else:
print('Looping Over')
time.sleep(1)
if __name__ == '__main__':
with Pool(2) as p:
p.map(testing, [3, 2])
sys.exit()
The output:
Count: 0
Looping Over
Count: 0
Looping Over
Count: 1
Looping Over
Count: 1
Looping Over
Count: 2
Looping Over
Count: 2
Exiting... ForkPoolWorker-2
Count: 3
Exiting... ForkPoolWorker-1
$
an explanation of this behaviour:
This happens because when you call sys.exit()
it raises systemExit Exception.since sys.exit()
ultimately only raises an exception, it will only exit the process in which is called and is not propagated further up to main processes.
Once all child processes exit the main process just sits there waiting for something to be returned from the child process. All child processes have already exited so there is nothing to return resulting in a forever wait
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With