65

Google I/O 2012 プレゼンテーションGo Concurrency Patternsで、Rob Pike は複数のゴルーチンが 1 つのスレッドに存在できると述べています。これは、それらがコルーチンとして実装されていることを意味しますか? そうでない場合、それらはどのように実装されていますか? ソースコードへのリンクは大歓迎です。

4

4 に答える 4

69

IMO、コルーチンは、制御を別のコルーチンに移すための明示的な手段をサポートすることを意味します。つまり、プログラマーは、コルーチンがいつ実行を中断し、その制御を別のコルーチンに渡すかを決定する方法でコルーチンをプログラムします (それを呼び出すか、戻る/終了する (通常は降伏と呼ばれます))。

Go の「ゴルーチン」は別のものです。特定の不確定なポイント1で制御を暗黙的に放棄します。これは、I/O 完了、チャネル送信などの (外部) リソースでゴルーチンがスリープしようとしているときに発生します。このアプローチは、チャネルを介した状態の共有と組み合わされます。プログラマーは、一連の軽量プロセスとしてプログラム ロジックを記述できるため、コルーチン ベースとイベント ベースの両方のアプローチに共通するスパゲッティ コードの問題が解消されます。

実装に関しては、(残念ながらあまり知られていない)「State Threads」ライブラリに非常に似ていると思いますが、かなり低レベルです(Goは依存していないlibcか、このようなものではなく、OSと直接対話します) kernel) — 概念が十分に説明されている ST ライブラリの入門書を読むことができます。


1実際、これらのポイントはコルーチンのポイントよりも決定的ではありませんが、プリエンプティブ マルチタスキング下の真の OS スレッドよりも決定的です。各スレッドは、任意の時点でスレッドの制御の流れの中でカーネルによって一時停止される可能性があります。
2021 年 5 月 28 日の更新:実際、Go 1.14 以降、ゴルーチンは (ほぼ) プリエンプティブにスケジュールされます。ただし、一般的なカーネルが管理するスレッドに対して実行するハードコアなプリエンプションではありませんが、以前よりもかなり近づいていることに注意してください。少なくとも、ビジー ループに入ると、ゴルーチンがプリエンプティブルになることは不可能になりました。

于 2013-08-05T15:10:02.410 に答える
61

そうではありません。Go FAQ セクションなぜスレッドではなくゴルーチンなのか? 説明します:

ゴルーチンは、並行処理を使いやすくするための一部です。独立して実行される関数 (コルーチン) を一連のスレッドに多重化するというアイデアは、しばらく前からありました。ブロッキング システム コールの呼び出しなどによってコルーチンがブロックされると、ランタイムは、同じオペレーティング システム スレッド上の他のコルーチンを別の実行可能なスレッドに自動的に移動して、ブロックされないようにします。プログラマーはこれを認識しません。これがポイントです。ゴルーチンと呼ばれる結果は、非常に安価になる可能性があります。スタックのメモリを超えるオーバーヘッドはわずか数キロバイトです。

スタックを小さくするために、Go のランタイムは、サイズ変更可能な制限付きスタックを使用します。新しく作成されたゴルーチンには数キロバイトが与えられますが、ほとんどの場合、これで十分です。そうでない場合、ランタイムはスタックを格納するためのメモリを自動的に拡大 (および縮小) し、多くのゴルーチンが適度な量のメモリに存在できるようにします。CPU オーバーヘッドは、関数呼び出しごとに平均約 3 つの安価な命令です。同じアドレス空間に数十万のゴルーチンを作成することは実際的です。ゴルーチンが単なるスレッドである場合、システム リソースははるかに少ない数で不足します。

于 2013-10-21T04:17:16.903 に答える
2

ゴルーチンは実行の独立した「スレッド」です。コルーチンに匹敵するものではないIMOです。最初の概算では、ゴルーチンは実際のOS スレッドによって実装できます。私の知る限り、それは gccgo の初期バージョンの場合でした。もう 1 つの違いは、ゴルーチンがプリエンプトされる可能性があることです。

現在の Go コンパイラは、ゴルーチンを非常に軽量なユーザー空間の「スレッド」として実装しています。たとえば、1つの明確な機能。グリーン スレッドとは、ゴルーチンを別の OS スレッドに切り替えることができるということです。

ここで関連する興味深い部分を見つけることができると思います: proc.c

于 2013-08-05T12:45:04.083 に答える