Asyncio hangs on exit in windows. Is it a bug?

I’m attempting to implement a Jupyter notebook like kernel with websockets 9.1 and multiprocessing, but have the problem that the asyncio loop in websockets doesn’t exit:

The parts are best illustrated like this:

image launches 3 sub processes using multiprocessing:

  • the notebook server (multiprocessing.Process)
  • the file service (multiprocessing.Process)
  • the socket server which uses websockets and asyncio
  • A client which communicates to the socket server.

The test runs setup() and all of the tests without any problem, but during teardown() the socket server just hangs.

This is what I see:

setup complete
notebook server ready
file service ready
socket server ready

# irrelevant output from the test suite redacted. All tests pass.

teardown complete

The command prompt just hangs here. I can see that all sub-processes have stopped except one.

When I then hit CTRL+C I get this:

Process socket server:
Traceback (most recent call last):
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 315, in _bootstrap
  File "C:\Data\github\websocket_trials\kernel\", line 225, in run
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\asyncio\", line 316, in run_forever
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\asyncio\", line 596, in run_forever
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\asyncio\", line 1854, in _run_once
    event_list =
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\asyncio\", line 434, in select
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\asyncio\", line 783, in _poll
    status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
Process launcher:
Traceback (most recent call last):
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 315, in _bootstrap
  File "C:\Data\github\websocket_trials\kernel\", line 48, in run
    if p.is_alive():
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 165, in is_alive
    returncode = self._popen.poll()
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 118, in poll
    return self.wait(timeout=0)
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 108, in wait
    res = _winapi.WaitForSingleObject(int(self._handle), msecs)
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 357, in _exit_function
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 149, in join
    res = self._popen.wait(timeout)
  File "C:\Users\madsenbj\Anaconda3\envs\py396\lib\multiprocessing\", line 108, in wait
    res = _winapi.WaitForSingleObject(int(self._handle), msecs)

I struggle to interpret the traceback. As I see both lib\asyncio and lib\multiprocessing so I’m not sure which is the culprit.

When I use cmd.exe the suite runs, but the process hangs like this:

When I use nosetests in pycharm the test suite runs to the end and closes all processes.

Do you have any suggestions to what could be wrong?


My suspicion is that this is an indeterminacy race bug between multiprocessing and asyncio.

How can I verify that it isn’t asyncio\ that has a lock at the same time as multiprocessing\ holds a lock and both are waiting for one another?


This one is still valid and unresolved. Any help / hints would be great.

1 Like

I think you need to kill your supprocesses when somebody presses control-C, etc. Possibly you could do:

import atexit

terminate_processes would kill all your subprocesses. The code would be located in your main or top level file. See at_exit docs at for simple example

1 Like

atexit was the answer. Thank @Milton_Mobley