Necesito poner un tiempo de espera en un proceso que se crea dentro de un hilo , sin embargo, encontré un comportamiento extraño y no estoy seguro de cómo proceder.
El siguiente código ejecutado en Linux produce un error extraño donde (si el número de subprocesos es mayor que 2 (mi computadora portátil tiene 8 núcleos) o el código se ejecuta en un bucle varias veces ) el proceso.join() no en realidad, espere a que finalice el proceso o que expire el tiempo de espera, pero simplemente continúe con la siguiente instrucción.
Si el mismo código se ejecuta en Windows con python 3.9 , da un error de importación circular en las bibliotecas sin ningún motivo.
Si se ejecuta con python 3.8 , funciona casi perfectamente hasta 256 subprocesos, luego da el mismo comportamiento extraño en process.join() que en Linux.
Error en Windows Python 3.9: ImportError: cannot import name 'Queue' from partially initialized module 'multiprocessing.queues' (most likely due to a circular import)
Además, si elimino el valor de retorno del proceso, elimino la Cola . En Linux , process.join() comienza a funcionar correctamente para n_threads arbitrariamente grandes. Sin embargo , ejecutar el código en un bucle aún da el error incluso para n_threads muy pequeños.
import random from multiprocessing import Process, Queue from threading import Thread def dummy_process(): return random.randint(1, 10) #function to retrieve process return value def process_returner(queue, function, args): queue.put(function(*args)) #function that creates the process with timeout def execute_with_timeout(function, args, timeout=3): q = Queue() p1 = Process( target=process_returner, args=(q, function, args), name="P", ) p1.start() p1.join(timeout=timeout) # SOMETIME IT DOES NOT WAIT FOR THE PROCESS TO FINISH if p1.exitcode is None: print(f"Oops, {p1} timeouts!")# SO IT RAISES THIS ERROR even if nowhere near 3 secods have passed raise TimeoutError p1.terminate() return q.get() if not q.empty() else None #thread that just call the new process and stores the return value in the given array def dummy_thread(result_array, index): try: result_array[index] = execute_with_timeout(dummy_process, args=()) except TimeoutError: pass def test(): #in loop because with low n_threads as 4 the error is not so common for _ in range(10): n_threads =8 results = [-1] * n_threads threads = set() for i in range(n_threads): t = Thread(target=dummy_thread, args=(results, i)) threads.add(t) t.start() for t in threads: t.join() print(results) if __name__ == '__main__': test()