目次
質問の内容
回避策
でラップし、
ホームページ バックエンド開発 Golang goroutine の作業が完了する前に Go プログラムが終了する

goroutine の作業が完了する前に Go プログラムが終了する

Feb 08, 2024 pm 10:57 PM
言語を移動

Go 程序在 goroutine 工作完成之前退出

この記事では、php エディターの Xiaoxin が、Go プログラムに関する重要な問題、つまり goroutine の作業が完了する前に終了する状況について紹介します。 Go 言語では、ゴルーチンはタスクを同時に実行できる軽量のスレッドです。ただし、ゴルーチンの作業が完了する前にプログラムが終了する可能性がある場合、プログラムがタスクを正しく完了できるように、この状況を処理する方法を理解する必要があります。次のコンテンツでは、この問題を調査し、それを解決するためのいくつかのソリューションを提供します。

質問の内容

チャンネルを適切にブロックして閉じる方法がわかりません。任意の数のワーカーを開始しているのですが、メイン関数がワーカーが完了する前に終了するか、チャネルが閉じられていないためにハングすることがわかりました。ワーカーがメイン チャネルを終了せずにチャネルを読み取るのを停止し、終了したら正常にチャネルを閉じてループを終了する、より良い方法が必要です。私が試みてもデッドロックに終わります。

待機グループの使用など、いくつかのことを試しましたが、問題は解決しません。 time.sleep を追加するとプログラムは期待どおりに動作しますが、コメントアウトすると何も行われないことに気付きました。

リーリー

これは、sleep を保持する実行可能なサンプル https://go.dev/play/p/qhqnj-ajqbi です。これは、スリープ タイムアウトがコメント化された壊れたコードです。

リーリー

また、defer wg.done()worker() 関数内に移動しようとしましたが、同じ問題であり、スリープなしでは機能しません。

リーリー

私は間違ったパラダイムを選択したのでしょうか、それとも単に間違ったパラダイムを使用しているだけなのでしょうか?

回避策

私は最初に「コードを機能させるためにコードを少し調整できますか? それともこの問題を再考する必要がありますか? 」と質問しました。その答えは次のとおりです。はい、小さな調整があることがわかりました。

チャネルに関する興味深い基本概念を学ぶ必要がありました。閉じたチャネルからデータを読み取ることができる、つまりチャネルをドレインすることができます。元の例で述べたように、チャンネルを閉じるのに適した場所が見つからないため、range は終了しません。また、他の創造的な方法で強制的にチャンネルを強制した場合でも、プログラムの動作が悪くなります。

    チャネル内のすべてのコンテンツを処理せずに終了しました
  • デッドロックまたは閉じたチャネルでの送信
これは、「

real」コードの微妙な違いによるもので、チャネル コンテンツ の処理に必要な時間は、# のデータを設定するのに必要な時間よりも長くなります。 ## チャンネルとモノが同期していません。 送信側でチャネルを閉じるための明確で実用的な方法がないため (チャネル チュートリアルの 99% で推奨されています)、複数のワーカーがチャネルを読んでいて、ワーカーがそのことを知らない場合、実際には最後の値が読み取られる main の goroutine を使用してこれを行うことは許容されます。

###解決###

ワーカーを独自の

sync.waitgroup

でラップし、

worker.wait()

を使用して プログラムの終了をブロックしました。送信するデータがなくなったら、チャネルを独立して close() します、つまり、ライターが独自の待機グループを使用して終了するのを待ってブロックします。範囲ループの終了ケースは、チャネルのデフォルト値が返されるとき、つまり、チャネルの終わりに到達したときに eof タイプに達すると終了するためです。ブロッキング ランデブー チャネルは、閉じられるまでエンドポイントを持ちません。 これに対する私の見解は、並列にプッシュされる値の数がわからない場合、バッファリングされていないチャネルはスコープ内にあるため、そのチャネルを閉じるまで go はそのチャネルの長さを知る方法がありません。 。 。閉じられているため、終了値または最後まで残っているものを読み取ることを意味します。 workers.wait() は完了するまでブロックされます。

解決された操作の例

https://www.php.cn/link/2bf0ccdbb4d3ebbcb990af74bd78c658 クローズドチャネルの読み取り例 https://www.php.cn/link/d5397f1497b5cdaad7253fdc92db610b

###出力### リーリー

以上がgoroutine の作業が完了する前に Go プログラムが終了するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

golang でリフレクションを使用してプライベート フィールドとメソッドにアクセスする方法 golang でリフレクションを使用してプライベート フィールドとメソッドにアクセスする方法 May 03, 2024 pm 12:15 PM

golang でリフレクションを使用してプライベート フィールドとメソッドにアクセスする方法

golang 関数で新しい関数を動的に作成するためのヒント golang 関数で新しい関数を動的に作成するためのヒント Apr 25, 2024 pm 02:39 PM

golang 関数で新しい関数を動的に作成するためのヒント

Go 言語でのパフォーマンス テストと単体テストの違い Go 言語でのパフォーマンス テストと単体テストの違い May 08, 2024 pm 03:09 PM

Go 言語でのパフォーマンス テストと単体テストの違い

Golang テクノロジーを使用して分散システムを設計する場合、どのような落とし穴に注意する必要がありますか? Golang テクノロジーを使用して分散システムを設計する場合、どのような落とし穴に注意する必要がありますか? May 07, 2024 pm 12:39 PM

Golang テクノロジーを使用して分散システムを設計する場合、どのような落とし穴に注意する必要がありますか?

機械学習で使用される Golang テクノロジー ライブラリとツール 機械学習で使用される Golang テクノロジー ライブラリとツール May 08, 2024 pm 09:42 PM

機械学習で使用される Golang テクノロジー ライブラリとツール

golang 関数の命名規則の進化 golang 関数の命名規則の進化 May 01, 2024 pm 03:24 PM

golang 関数の命名規則の進化

モバイルIoT開発におけるGolangテクノロジーの役割 モバイルIoT開発におけるGolangテクノロジーの役割 May 09, 2024 pm 03:51 PM

モバイルIoT開発におけるGolangテクノロジーの役割

golang 変数パラメータは関数の戻り値に使用できますか? golang 変数パラメータは関数の戻り値に使用できますか? Apr 29, 2024 am 11:33 AM

golang 変数パラメータは関数の戻り値に使用できますか?

See all articles