web-dev-qa-db-ja.com

Goゴルーチンはコルーチンですか?

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

50
Sławosz

そうでもない。 Go FAQセクション スレッドの代わりにゴルーチンを使用する理由は何ですか? の説明:

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

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

47
K Z

IMO、コルーチンはexplicit別のコルーチンに制御を移す手段のサポートを意味します。つまり、プログラマーは、コルーチンが実行を中断し、その制御を別のコルーチンに渡すタイミングを決定する方法でコルーチンをプログラムします(呼び出しまたは復帰/終了(通常、yieldingと呼ばれる)によって)。

Goの「goroutines」は別のものです。特定のindeterminateポイントでコントロールを暗黙的に降伏します1 ゴルーチンがI/O完了、チャネル送信などの(外部)リソースでスリープしようとすると発生します。チャネルを介した状態の共有とこのアプローチを組み合わせると、プログラマはプログラムロジックをsequentialコルーチンおよびイベントベースのアプローチの両方に共通するスパゲッティコードの問題を取り除く軽量プロセス。

実装に関しては、(残念ながらあまりよく知られていない) "State Threads"ライブラリ と非常に似ていると思います。Goはlibcまたはこのようなもので、OSカーネルと直接対話します)—概念が非常によく説明されているSTライブラリの入門書を読むことができます。


1 実際、これらのポイントはコルーチンよりも確定的ではありませんが、 preemptive multitasking の下の真のOSスレッドよりも確定的であり、各スレッドは任意の時点およびフローでカーネルによって中断される可能性がありますスレッドの制御の。

53
kostix

ゴルーチンが適切なコルーチンであるか、類似のものであるかは、 https://groups.google.com/forum/?fromgroups=#!forum/golang-nuts でよく説明されています。一部の人々はそのような微妙さについて議論することができますが、それのほとんどのために:ゴルーチンはコルーチンです。

https://docs.google.com/document/d/1TTj4T2JO42uD5ID9e89oa0sLKhJYD0Y_kqxDv3I3XMw/edit を参照して、スケジューラの動作を理解してください。

4
Volker

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

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

ここで関連するいくつかの関連するビットを見つけることができると思います: proc.c

2
zzzz