6

私はGILについて読んでいましたが、これにメインスレッドが含まれるかどうかは実際には指定されていませんでした(私はそう思います)。私が尋ねる理由は、辞書を変更するスレッド設定のプログラムがあるからです。メインスレッドはプレーヤーの入力に基づいて追加/削除し、スレッドはデータの更新と変更をループします。

ただし、場合によっては、スレッドが辞書キーを繰り返し処理して、それらを削除できることがあります。いわゆるGILがあり、それらが順番に実行される場合、なぜdict変更エラーが発生するのですか?一度に1つだけ実行することが想定されている場合、技術的にはこれは発生しないはずです。

誰かがそのようなことに光を当てることができますか?ありがとうございました。

4

4 に答える 4

10

それらは同時に実行されていますが、同時に実行されていません。反復はインターリーブされる場合があります。パイソンの引用:

一度に 1 つのスレッドのみがPythonバイトコードを実行することを保証するために、CPython インタープリターによって使用されるメカニズム。

したがって、2 つのforループが同時に実行される可能性があります。(たとえば) 2 つdel dict[index]の が同時に実行されることはありません。

于 2011-01-20T15:16:46.900 に答える
6

GIL は Python バイトコード レベルでロックし、メイン スレッドを含むすべてのスレッドに適用されます。1 つのスレッドが辞書を変更し、別のスレッドがキーを反復している場合、それらは互いに干渉します。

「一度に 1 つだけ実行する」というのは本当ですが、粒度の単位を理解する必要があります。CPython の GIL の場合、粒度はバイトコード命令であるため、実行は任意のバイトコードでスレッド間を切り替えることができます。

于 2011-01-20T15:15:48.787 に答える
3

gil は、2 つのスレッドがインタープリターの状態を同時に変更するのを防ぎます。プロセス全体よりも小さい粒度で、スレッドの一貫性の制約や、あらゆる種類のミューテックスを提供しません。2 つのスレッドで dict を読み取って変更する必要がある場合は、ミューテックスを使用する必要があります

于 2011-01-20T15:17:00.633 に答える
1

Python は、あなたが思っている以上に頻繁にスレッドを切り替えます。一度に実行するのは「1 つだけ」であり、技術的にはその通りですが、それは「1 つ」の定義によって異なります。Python のアトミック操作は非常に小さいです。例: 単一の項目を辞書に追加します。ディクショナリ全体の反復は中断される可能性があります。

プログラムのアトミック操作を分離するには、スレッドライブラリのロック オブジェクトを使用する必要があります。

于 2011-01-20T15:19:27.273 に答える