I have a simplified program in python 3.6, which runs multiple threads. Each thread then spawns a process pool and run a job in parallel.
Now for some reason, the code works fine on Windows, but after several cycles, hangs on Linux. This could be due to Linux using fork for creating new processes, instead of spawn. The behavior can be changed, but spawning the processes is too slow for my needs.
Here is the code:
import time
import random
from threading import Thread
from multiprocessing import Pool
NUM_PROCESSES = 2
NUM_TRIALS = 3
random.seed(42)
class TestPool:
def process(self):
opt_profiles = ['P1', 'P2', 'P3', 'P4']
input_data = [1, 2, 3]
for _ in range(100):
threads = []
try:
for opt_profile in opt_profiles:
thread = self.process_async(opt_profile, input_data)
threads.append(thread)
finally:
print('Waiting for threads to be finished')
for thread in threads:
thread.join()
print('Threads are finished')
def process_async(self, opt_profile, input_data):
thread = Thread(target=self._process_asynch_pool, args=[opt_profile, input_data])
thread.start()
return thread
def _process_asynch_pool(self, opt_profile, input_data):
print(f'Processing profile: {opt_profile}, data: {input_data}')
p = Pool(NUM_PROCESSES)
print(f'Running profile: {opt_profile}')
processed_data = p.map(self._process_asynch_data, input_data)
print(f'Closing profile: {opt_profile}')
p.close()
print(f'Joining profile: {opt_profile}')
p.join()
print(f'Processes have joined.')
def _process_asynch_data(self, input_data):
print(f'Received data: {input_data}')
result = input_data * 10
time.sleep(1)
return result
if __name__ == '__main__':
pool = TestPool()
pool.process()
The code hangs on the thread.join() line, but the logs indicate that every process has finished its job.
Edit: In addition to the original system (CentOS, Python3.6), I can reproduce the issue on Ubuntu (WSL) with Python3.8.