オンラインでたくさんの記事を読んだのですが、まだ混乱しています。誰かこれら 2 つの概念をわかりやすく説明してもらえませんか?
Python のマルチスレッド コーディングでは、通常、スレッドの run メソッドで while True 無限ループを使用し、ループ本体の最後で queue.task_done を呼び出してキューを削除し、キューの join を呼び出します。メインスレッドが直接終了しないように、メインスレッドをブロックする方法ですが、このマルチスレッドコーディング方法は合理的でしょうか?バグはあるのでしょうか?さらに、run で呼び出す無限ループはスピン ロックと呼ばれるかどうかも聞きたいです。
まず、ミューテックス ロックとは何か、そしてそれが何を意味するのかを理解する必要があります。
2 つのスレッド A と B が同じメモリにアクセスする場合です。
理想的には、A が完全に実行された後に B が実行されるべきです。ただし、メカニズムが使用されない場合、A が途中で実行されると、B が CPU を占有します。このメモリを処理するために B が実行され、B が実行を完了し、A が再び CPU を取得すると、メモリのデータは間違っているのではないでしょうか?
メモリデータのセキュリティのため。相互排他的なテクノロジが使用されます。A がこのメモリにアクセスするときは、まずこのメモリにフラグ (ロックと呼ばれます) があるかどうかを判断し、そうでない場合はフラグ (ロック) をこのメモリに追加します。メモリに保存され、処理後に A がロックを解除します。 A がメモリを処理している間に B がアクセスすると、B はこのメモリに使用中サイン (ロック) があることがわかり、B はいくつかの動作をする可能性があります。動作 1: CPU を占有します。継続的にループしてロックのステータスをテストします。スレッドはハング (スリープ) せず、ビジー待機状態になります。この動作を採用するロックはスピン ロックと呼ばれます。動作 2: スレッド B はスリープしてブロックし、A が実行を終了してロックが解除されるまで CPU を放棄し、その後メモリを使用します。この動作はミューテックス ロックと呼ばれます。これを見れば、ロックが相互排他を実装する同期メカニズムであることが理解できると思います。スピン ロックは、ミューテックス ロックの単なるケースです (待機中に CPU のミューテックス ロックを占有します)。
名前に惑わされないでください。その仕組みを理解するには、名前を変えてでも理解する必要があります、
参考リンク リンク説明
1. Python マルチスレッド実行メソッドで while ループを使用する場合、ループ本体でプログラム停止メカニズムが使用されていない場合は、実行を継続します。そのため、投稿者が適切にコーディングしたい場合は、セマフォまたはその他の変数メカニズムを使用してループ本体に通知します。キューが空である場合は、直接ブレークしてループを終了します。
2. run の無限ループはスピン ロックではありません。ループ内でリソースの競合がある場合、ロックが追加されますが、このロックも相互排他ロックです。
リーリーPython のロックはスピンロックではなくセマフォを使用します。
スピンロック: 複数のスレッドが同時に同じリソースにアクセスするときに、リソースの一貫性のない読み取りと変更を防ぐために設定されるロックです。あるスレッドがリソースにアクセスするときに、そのスレッドがすでにリソースを占有している場合、後者のスレッドは待機します。このとき、後者は (スリープせずに) CPU を実行し続け、前者が占有しているリソースが解放されるかどうかを検出します。この仕組みがスピン ロックです。 。
ミューテックスロック: 目的はスピンロックと同じですが、スレッドがリソースを占有するとロックが追加され、後者のスレッドがリソースにアクセスすると、リソースが占有されているためスリープ状態になります。 、リソースが解放されるのを待ちます。最後に、待機中のスレッドにセマフォを通じて通知が送信されます。
Pythonコードはこのプロセスに従って実行されます
GILをセットアップ
特定のスレッドに切り替えます
走る
スレッドが終了し、スリープ状態に設定されます
GILのロックを解除
上記の操作を繰り返します
GIL のせいか、Python ではスピン ロックを見たことがないようで、主にミューテックス ロックが使用されています。
以下は私がマルチスレッドを書くために使用した方法です、参考までに〜
リーリーキューなのでQueueのQueue().get()でキューからアイテムを削除して返す説明をしています