チャネルを使用する場合、ゴルーチンの実行順序はどうなりますか?

王林
リリース: 2024-02-09 13:48:09
転載
1257 人が閲覧しました

使用通道时,goroutine 的执行顺序是什么?

php エディタ Baicao は、よくある質問に答えます: 「チャネルを使用する場合、ゴルーチンの実行順序は何ですか?」 Go 言語では、ゴルーチンは軽量です スレッドは同時に実行できます。コルーチン間の通信にチャネルを使用する場合、チャネルの受信操作と送信操作はブロックされます。つまり、他のコルーチンの操作が完了するのを待ちます。したがって、複数のゴルーチンが同時にチャネルを操作する場合、それらの実行順序は不確実であり、各コルーチンのスケジューリングに依存します。つまり、どのゴルーチンが最初に実行され、どのゴルーチンが後に実行されるかを決定することは不可能であり、これは Go 言語のスケジューラによって決定されます。

質問内容

チャネル使用時のゴルーチンの実行順序はどうなりますか?チャネルの書き込みまたは読み取りにより、現在のゴルーチンが停止すると思います。しかし、私のテストコードは次のルールに従っていません:

リーリー

このプログラムがどのように機能するか:

1.チャンネルの作成

2. goroutine を作成します (開始せず、初期化のみ)

3. 印刷: 番号を書き留めます: 10

4. チャンネル 10 に録音します。キー機能をロックします。

####5. 最も重要なことはブロックされることです。 sum ゴルーチンを開始します。

6. 合計関数を出力: Func 'sum' start

7. 合計関数がループ内で実行され、次のように出力されます: "To begin"

8. "ch" から数値 10 を読み取り、次のように出力します: "Read from ch: 10"

9.次のステップ。 「完了」と出力し、次の繰り返しに進みます。

###10。 「で始まる」を印刷し、「で」と書いてみます。しかし、チャンネルは空です。クォータを停止して本線に入ります

###...何回も何回も。

それでは、私が見たいのは:

リーリー

しかし、私は次のことを目にしました:

リーリー ###どうすればいいの? main 関数は、読み取りを行わずにチャネルに 2 回書き込みます。

また、次のコール数を変更する場合:

リーリー

エラーが分かりません。しかし、誰も最後のメッセージを読みませんでした

例: このメッセージの前。

解決策

Goroutine は同時に実行されます。複数のコアを備えたシステムでは、それらを並行して実行できます。詳細は、Go ランタイムのスケジューラー実装によって異なります。チャネル通信などの同期操作を除いて、あらゆる意図と目的において、物事はランダムな順序で発生します。

これは当てはまらず、実際に起こっていることでもありません (チャネルがバッファリングされていない限り)。 Println 呼び出しは送信操作の前に発生し、メインの Goroutine は印刷後、合計 Goroutine が受信できる状態になるまでブロックされます。

「Read from ch: 30」と表示されるかどうかもランダムです。メインブロックはそれが実行されるまでブロックされるため、対応する受信操作が実行される必要があります。ただし、受信が発生した後、Println より前に main が戻る可能性があり、他の goroutine の存在に関係なく、main が戻るとプログラムはすぐに終了します。チャネルがバッファリングされている場合、この問題が発生する可能性が高くなります。

しかし、実際にはそうではありません。受信者が 2 つしかない場合は、常にデッドロックが発生します:

https://go.dev/play/p/ qFVh529mkqR

以上がチャネルを使用する場合、ゴルーチンの実行順序はどうなりますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:stackoverflow.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート