ホームページ  >  記事  >  バックエンド開発  >  goroutine が次のミューテックス コードでスタックする原因は何ですか?

goroutine が次のミューテックス コードでスタックする原因は何ですか?

王林
王林転載
2024-02-13 18:57:07651ブラウズ

是什么导致我的 goroutine 在以下互斥体代码中陷入僵局?

php エディターの Shinichi が、よくある質問に答えます。「ゴルーチンが次のミューテックス コードでスタックする原因は何ですか?」 同時プログラミングでは、ミューテックス ロック (ミューテックス) を使用します。共有リソースの競合を解決するための一般的な方法の説明。ただし、コードに問題がある場合、ゴルーチンがデッドロックになり、実行を続行できなくなる可能性があります。次に、この問題の考えられる原因と解決策を詳しく説明します。

質問内容

キーごとに個別のロックを設定してキーのマップを保存しようとしています。 特定のキーのロックを作成するときは、グローバル ミューテックスを使用してマップに書き込みます。

キーのロックの作成が完了したら、新しいロックを使用し、作業が完了したらロックを解除します。 現在、コードをテストするために単一のキーを変更しようとしています。

これはコードです:

リーリー

なぜロックを取得できないのかわかりません。 プレイグラウンド リンク: https://go.dev/play/p/-co0xaxpuy0

Solution

mylock はグローバル ミューテックスと個々のミューテックスをロックできます。これにより、場合によってはロックを解除できなくなります:

  1. ゴルーチン 1 は mylock(2) を呼び出します。これにより、単一のロック l2 が期待どおりにロックされます。
  2. ゴルーチン 2 は mylock(2) を呼び出します。グローバル ロックを取得し、l2 が解放されるまでブロックします。待機中、グローバル ロックは保持され続けます。
  3. ゴルーチン 1 は myunlock(2) を呼び出します。グローバル ロック (ゴルーチン 2 によって保持されている) が解放されるのを待っているため、ブロックされます。これは行き詰まりです。

この問題を解決するには、グローバル ロックが保持されている間に、ロックを (解除) するのではなく、個々のロックを返します。 myunlock関数が不要になります:

リーリー

パフォーマンスを向上させるために、グローバル読み取りロックのみを保持しながら、最初に単一のロックが存在するかどうかを確認できます (これにより、count が表す内容が変更されることに注意してください)。 リーリー

以上がgoroutine が次のミューテックス コードでスタックする原因は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。