Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

RuntimeError after ctrl-C interrupt when asyncio is closing the threadpool #96827

Copy link
Copy link
Closed
@xitop

Description

@xitop
Issue body actions

Test program based on a SO question; press Ctrl-C after "coro stop" and before "thread stop":

import asyncio
import time

async def main():
    print("coro start")
    loop = asyncio.get_running_loop()
    loop.run_in_executor(None, blocking)
    await asyncio.sleep(1.0)
    print("coro stop")

def blocking():
    print("thread start")
    time.sleep(3.0)
    print("thread stop")

try:
    asyncio.run(main())
except KeyboardInterrupt:
    print("interrupted!")

The output is as expected:

coro start
thread start
coro stop
^Cinterrupted!
thread stop

but a stack trace is printed to stderr:

exception calling callback for <Future at 0x7fb3e38bc0a0 state=finished returned NoneType>
Traceback (most recent call last):
  File "/usr/lib64/python3.10/concurrent/futures/_base.py", line 342, in _invoke_callbacks
    callback(self)
  File "/usr/lib64/python3.10/asyncio/futures.py", line 399, in _call_set_state
    dest_loop.call_soon_threadsafe(_set_state, destination, source)
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 795, in call_soon_threadsafe
    self._check_closed()
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception in thread Thread-1 (_do_shutdown):
Traceback (most recent call last):
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 576, in _do_shutdown
    self.call_soon_threadsafe(future.set_result, None)
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 795, in call_soon_threadsafe
    self._check_closed()
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 578, in _do_shutdown
    self.call_soon_threadsafe(future.set_exception, ex)
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 795, in call_soon_threadsafe
    self._check_closed()
  File "/usr/lib64/python3.10/asyncio/base_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

The interrupt occurs in asyncio.run at line 49 in the file asyncio/runners.py

 39     loop = events.new_event_loop()
 40     try:
 41         events.set_event_loop(loop)
 42         if debug is not None:
 43             loop.set_debug(debug)
 44         return loop.run_until_complete(main)
 45     finally:
 46         try:
 47             _cancel_all_tasks(loop)
 48             loop.run_until_complete(loop.shutdown_asyncgens())
 49             loop.run_until_complete(loop.shutdown_default_executor())
 50         finally:
 51             events.set_event_loop(None)
 52             loop.close()

The control returns to the main program (except KeyboardInterrupt), but the cleanup waits
until the spawned thread terminates and at that time the event loop is closed and the RuntimeError
occurs.

In my opinion, no RuntimeError should happen. Given that the entire user's program is guarded by
try-except which successfully catches the KeyboardInterrupt, there is very little a programmer
can do to avoid this situation maybe except suppressing the output by redirecting the stderr to /dev/null.

Your environment

Python 3.10

Metadata

Metadata

Assignees

Labels

3.10only security fixesonly security fixes3.11only security fixesonly security fixes3.12only security fixesonly security fixestopic-asynciotype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

Status

Done
Show more project fields

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.