[issue22926] asyncio: raise an exception when called from the wrong thread

STINNER Victor report at bugs.python.org
Sun Dec 21 00:41:07 CET 2014


STINNER Victor added the comment:

Rebased patch which now always check the thread, even in release mode.

Summary of the current version of the patch (check_thread-2.patch):

- call_soon/call_at now checks if they are called from the thread running the event loop
- the check is only done when the event loop in running
- the check is always done, in relase and debug mode (we may only do it in release mode if you consider that the overhead is too high, see benchmark numbers below)
- add a unit test for the thread check
- since the check is only done when the event loop in running, we don't need the hack to avoid the thread check in the proactor event loop, for "self._call_soon(self._loop_self_reading, ())"
- replace the _running attribute with a new _owner attribute in BaseEventLoop


> Victor, can you benchmark this?

Here is a benchmark for call_soon(): bench_call_soon.py. It computes the performance of one call to call_soon() in average. It uses 10,000 iterations, the test is run 5 times and the minimum timing is displayed.

Since a call to traceback.extract_stack() takes more than 65 us, whereas a call to call_soon() in release mode takes 2.8 us, I removed the call in Handle constructor for the benchmark to focus on the thread check.

- asyncio without extract_stack(), in release mode: 2491 ns per call
- asyncio without extract_stack(), in debug mode: 3588 ns per call (1.4x slower, +1097 ns)
- asyncio without extract_stack(), with check_thread-2.patch: 2721 ns per call (1.1x slower, +230 ns)

The overhead of check_thread-2.patch is +230 ns (1.1x slower) per call to call_soon().

Do you consider that the overhead is low enough to run the check even in release mode?

At least on Linux, threading.get_ident() is not a system call. Performances may be different on other platforms (ex: BSD, Windows).

In check_thread-2.patch, I "inlined" the thread check directly in call_at() and call_soon(). For performance, but also because the check only takes 2 lines, and so the error message can contain the function name (call_soon/call_at).

----------
Added file: http://bugs.python.org/file37518/check_thread-2.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue22926>
_______________________________________


More information about the Python-bugs-list mailing list