New submission from STINNER Victor <vstin...@python.org>:

When a thread gets a signal, SIGNAL_PENDING_SIGNALS() sets signals_pending to 1 
and eval_breaker to 1. In this case, _PyEval_EvalFrameDefault() calls 
handle_signals(), but since it's not the main thread, it does nothing and 
signals_pending value remains 1. Moreover, eval_breaker value remains 1 which 
means that the following code will be called before executing *each* bytecode 
instruction.

    if (_Py_atomic_load_relaxed(eval_breaker)) {
        (...)
        opcode = _Py_OPCODE(*next_instr);
        if (opcode == SETUP_FINALLY || ...) {
            ...
        }
        if (_Py_atomic_load_relaxed(&ceval->signals_pending)) {
            if (handle_signals(tstate) != 0) {
                goto error;
            }
        }
        if (_Py_atomic_load_relaxed(&ceval->pending.calls_to_do)) {
            ...
        }

        if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) {
            ...
        }
        if (tstate->async_exc != NULL) {
            ...
        }
    }

This is inefficient.

I'm working on a PR modifying SIGNAL_PENDING_SIGNALS() to not set eval_breaker 
to 1 if the current thread is not the main thread.

----------
components: Interpreter Core
messages: 364580
nosy: vstinner
priority: normal
severity: normal
status: open
title: Inefficient sigal handling in multithreaded applications
versions: Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue40010>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to