python / python/cpython

Callbacks pended by `Py_AddPendingCall` will never be invoked if the main thread doesn't release GIL

オープン
#95,820 コメント 6 件 リアクション 0 件 担当者 1 名 GitHub で見る

@markshannon がすでに取り組んでいます。

2022年8月23日 から。

3.10 3.11 3.12 interpreter-core type-bug
主要言語
Python
スター
77.2k
フォーク
36k
PR マージ指標
PR 指標を取得中

説明

According to the Py_AddPendingCall's document (https://docs.python.org/3/c-api/init.html#c.Py_AddPendingCall), a pended callback function should be invoked when:

It will be called asynchronously with respect to normally running Python code, but with both these conditions met:

- on a bytecode boundary;

- with the main thread holding the global interpreter lock.

So if the main thread is processing an endless loop like:

while True:
    pass

A callback pended from another thread by Py_AddPendingCall should still be able to be invoked.

It works in Python 3.8.13, but doesn't work in Python 3.9.13. In 3.9.13, the callback pended by Py_AddPendingCall will never be invoked in this case.

The root cause may be here: https://github.com/python/cpython/pull/19091/files#diff-c22186367cbe20233e843261998dc027ae5f1f8c0d2e778abfa454ae74cc59deL152-L153. After this change, pending a callback from a non-main thread will not set the ceval2->eval_breaker to be true. So when the main thread is trapped in an endless loop and keeps holding GIL, pending callbacks will never be invoked.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。