import sys, os import time import multiprocessing import threading def main(): # Expected result when running this code: # exits with output "thread_run got EOFError as expected"+"thread joined" # Actual result: deadlock in thread.join() / con.recv() print(f'main() using {sys.version}, pid={os.getpid()}', flush=True) pipe_read, pipe_write = multiprocessing.Pipe(duplex=False) p = multiprocessing.Process( target=worker_main, name='Worker', args=( pipe_write, ), ) print('starting', flush=True) p.start() print('started', flush=True) pipe_write.close() # Close our copy of the worker's end of the connection ASAP thread = threading.Thread(target=lambda: thread_run(pipe_read)) thread.start() print('running', flush=True) # time.sleep(1) # Error no longer reproduces when adding this sleep print('killing', flush=True) p.kill() print('killed', flush=True) p.join() print('process joined', flush=True) thread.join() print('thread joined', flush=True) def thread_run(con): try: msg = con.recv() except EOFError: print('thread_run got EOFError as expected', flush=True) else: print(f'thread_run received something: {msg}', flush=True) def worker_main(con): print('worker_main()', flush=True) time.sleep(5) if __name__ == '__main__': main() # On deadlock, only the main process is alive, with the following stacks: # Process 10632: c:\Python39\python.exe z:\test\deadlock.py # Python v3.9.1 (C:\Python39\python.exe) # # Thread 7860 (active) # ntdll!NtWaitForSingleObject + 0x14 # KERNELBASE!WaitForSingleObjectEx + 0x8e # python39!_PyCOND_WAIT_MS + 0x3c # python39!PyCOND_WAIT + 0xf # python39!EnterNonRecursiveMutex + 0x115 # python39!PyThread_acquire_lock_timed + 0x14d # python39!acquire_timed + 0x90 # python39!lock_PyThread_acquire_lock + 0x31 # _wait_for_tstate_lock (threading.py:1049) # join (threading.py:1033) # main (deadlock.py:32) # (deadlock.py:48) # Thread 15344 (active) # ntdll!NtWaitForMultipleObjects + 0x14 # KERNELBASE!WaitForMultipleObjectsEx + 0xf0 # KERNELBASE!WaitForMultipleObjects + 0xe # python39!_winapi_WaitForMultipleObjects_impl + 0x11c # python39!_winapi_WaitForMultipleObjects + 0x53 # _recv_bytes (multiprocessing\connection.py:310) # recv (multiprocessing\connection.py:255) # thread_run (deadlock.py:37) # (deadlock.py:23) # run (threading.py:892) # _bootstrap_inner (threading.py:954) # _bootstrap (threading.py:912)