You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Inefficient signal handling in multithreaded applications #84191
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2020-03-25.17:33:17.981>created_at=<Date2020-03-19.00:57:19.125>labels= ['interpreter-core', '3.9', 'performance']
title='Inefficient signal handling in multithreaded applications'updated_at=<Date2020-05-05.15:27:40.795>user='https://github.com/vstinner'
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.
changed the title [-]Inefficient sigal handling in multithreaded applications[/-][+]Inefficient signal handling in multithreaded applications[/+]on Mar 20, 2020
changed the title [-]Inefficient sigal handling in multithreaded applications[/-][+]Inefficient signal handling in multithreaded applications[/+]on Mar 20, 2020
Activity
vstinner commentedon Mar 19, 2020
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.
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.
vstinner commentedon Mar 19, 2020
I found this issue while working on PR 19066 of bpo-39984.
vstinner commentedon Mar 19, 2020
New changeset 5a3a71d by Victor Stinner in branch 'master':
bpo-40010: Optimize signal handling in multithreaded applications (GH-19067)
5a3a71d
vstinner commentedon Mar 19, 2020
New changeset a36adfa by Victor Stinner in branch 'master':
bpo-39877: 4th take_gil() fix for daemon threads (GH-19080)
a36adfa
vstinner commentedon Mar 20, 2020
New changeset da2914d by Victor Stinner in branch 'master':
bpo-40010: Pass tstate to ceval GIL functions (GH-19077)
da2914d
vstinner commentedon Mar 20, 2020
New changeset d2a8e5b by Victor Stinner in branch 'master':
bpo-40010: COMPUTE_EVAL_BREAKER() checks for subinterpreter (GH-19087)
d2a8e5b
vstinner commentedon Mar 20, 2020
New changeset d831688 by Victor Stinner in branch 'master':
bpo-40010: Optimize pending calls in multithreaded applications (GH-19091)
d831688
[-]Inefficient sigal handling in multithreaded applications[/-][+]Inefficient signal handling in multithreaded applications[/+][-]Inefficient sigal handling in multithreaded applications[/-][+]Inefficient signal handling in multithreaded applications[/+]ericsnowcurrently commentedon May 5, 2020
Good catch on this, Victor. Thanks for doing it.