I am struggling with using Python "multiprocessing" module. I want to fill a queue with simple things and to print things when the queue isn't empty, which will let me know that one of my processes has terminated.
You will find a minimal example below:
I create an empty queue
q
I create a list of processes
processes
, as many as my CPU will let me; I start every process in the list as soon as it's created (proc.start()
)The target function of each process is a very simple function
f
which first waits for 2 seconds, and then writes 'hello' in the queue (which is its only parameter)Afterwards, I check every 0.5 second if
q
isn't empty (it should receive a 'hello' every time one of my processes successfully executes functionf
), and I also check whether my processes are alive or not.
I'm facing 2 issues here:
- from the very first attempt, all my processes are not alive;
- nothing is ever printed, which means that queue
q
never successfully receives any 'hello'.
You will find my code below.
# -*- coding: utf-8 -*-
"""
Created on Fri Dec 4 12:21:23 2020
@author: rbourgeon
"""
import multiprocessing as mp
import time
def f(q):
time.sleep(2)
q.put('hello')
pool_size = mp.cpu_count() - 1
print(f'pool_size is {pool_size}')
q = mp.Queue()
processes = []
num_active_processes = 0
# Starting processes
while len(processes) < pool_size:
proc = mp.Process(target=f,
args=(q,)
)
processes.append(proc)
proc.start()
print(f'{len(processes)} jobs started')
num_active_processes += 1
# Checking if queue is empty every 0.5 second. If not empty, we pop an element
# and we print it
for i in range(1, 100):
print(f'\nAttempt #{i}')
if not q.empty():
print(q.get())
time.sleep(0.5)
print(processes)
print([p.is_alive() for p in processes])
The following gets printed to the console:
pool_size is 7
1 jobs started
2 jobs started
3 jobs started
4 jobs started
5 jobs started
6 jobs started
7 jobs started
Attempt #1
[<Process(Process-8, stopped[1])>, <Process(Process-9, stopped[1])>, <Process(Process-10, stopped[1])>, <Process(Process-11, stopped[1])>, <Process(Process-12, stopped[1])>, <Process(Process-13, stopped[1])>, <Process(Process-14, stopped[1])>]
[False, False, False, False, False, False, False]
Attempt #2
[<Process(Process-8, stopped[1])>, <Process(Process-9, stopped[1])>, <Process(Process-10, stopped[1])>, <Process(Process-11, stopped[1])>, <Process(Process-12, stopped[1])>, <Process(Process-13, stopped[1])>, <Process(Process-14, stopped[1])>]
[False, False, False, False, False, False, False]
and so on until last attempt.
which means that a) all of my processes died within 0.5 seconds b) in the meanwhile, none of them successfully executed function f because the "print" line is never executed (and therefore the queue is empty).