プログラミング言語「Go 」の最も人気のある点の1つは、コンピュータが多くのタスクを同時に達成する能力を第一級にサポートしていることです。コンピュータがコードの単一フローをより速く実行することから、多くのストリームを同時に実行することに移行するにつれ、コードを同時に実行する能力はプログラミングにおいてより重要になりつつあります。より高速に動作するプログラムを作るために、プログラマはシステムの各同時実行要素が他の要素から独立して実行できるように、同時に実行するように設計しなければなりません。
Go の機能であるGoroutines とチャンネルを一緒に使うと、同時実行が容易になります。Goroutines はこの機能のための基本的な原型を提供します。Goroutines はメモリ空間、スレッド間相互作用、ネットワーク接続に関してコストが低くなっています。また、スレッドよりも起動時間が短く、多くのプログラミング言語でサポートされています。要するに、Go は、Javaや他のプログラミング言語がスレッドと呼んでいるものとして、Goroutines を参照しているのです。
Goroutines とは?
ゴルーチンとは、プログラムの他の部分と同時に実行されるGolangの単純な実装スレッドです。Goroutines 、ゴルーチンの作成コストが非常に低いため、標準的なスレッドに似せると手頃です。そのため、Go 、並行プログラミングに広く採用されています。すべてのプログラムは、少なくとも1つのメインゴルーチンと呼ばれるゴルーチンで構成されています。メインゴルーチンは他のすべてのゴルーチンを制御するため、メインゴルーチンが終了するとスクリプト内の他のすべてのゴルーチンも終了します。ゴルーチンは常にバックグラウンドで動作しています。
例例:ノートブックに何か書いていてお腹が空いたので、一休みして何か食べる。そしてまた書き始める。あなたは今、兼業とみなされる時間枠で2つの役割(書くことと食べること)をしています。ここで注目すべきは、この2つの作業(書くことと食べること)は、やはり同時に完了させる必要があることです。項目が同時に完了することを並行性と呼びます(ポテトチップスを食べながら携帯電話を使うことを想像してみてください)。同時並行には、同時に多くのものと相互作用することが含まれます。並行性(多くのことを同時に行うこと)は、これのサブクラスで(同時に行う必要はない)何らかのタイムテーブルがある。
関数呼び出しにgoキーワードを適用することで、ゴルーチンを追加することができます。関数呼び出しにgoキーワードを適用したら、並行処理を性能に設定することになる。しかし、その前に、goキーワードを実行に適用した場合の効果を確認しておこう。あるプログラムの中に2つのゴルーチンがあるとしよう。package main import" というテキストがプログラムのエントリになります。Go において、パッケージのmain importは宣言的なimport文である。メインゴルーチン(first goroutine)は暗黙の了解です。go (f) を実行すると、2番目のゴルーチン(0)が生成されます。通常、私たちのソフトウエアは、関数を実行すると、次の行に進む前に一次関数内のすべてのコマンドを実行します。
そのため、ゴルーチンによって素早く処理を実行し、次のステップに進むことができます。その結果、scanlnメソッドが追加されました。そうしないと、すべての数値を表示する前にコードが終了してしまいます。Goroutines は簡単に作成でき、大量に作成することができます。このソフトを実行すると、ゴルーチンが同時進行ではなく、逐次的に動作しているように見えることに気がつくでしょう。
スレッドに比べたGoroutines の利点
Goroutines コストが安い
Goroutines は、他の処理に比べてコストが低い。マスサイズは数キロバイトで、プログラムの要求に応じて拡大・縮小できる。スタックサイズを定義しなければならず、永久的なものであるスレッドとは対照的である。
多重化されたものがあるGoroutines
オペレーティングシステムのスレッドには、多重化されているものはほとんどありません。数百のゴルーチンを持つプログラムでは、プロセスは1つだけかもしれません。残りのゴルーチンは新しいオペレーティング・システム・プロセスに転送されます。そのプロセス内のいずれかのゴルーチンが、ユーザーの介入を求めている時などに、スタックしたとする。ランタイムはこれらをそれぞれ管理し、我々開発者はこれらの微妙な複雑さから隔離されながら同時に管理するための明確なAPIを与えられている。
Goroutines チャンネルを使ったコミュニケーション
Goroutines チャネルを使って会話する関連するメモリを共有する際に、レース状況が発生しないようにすることを意図している。チャネルは、ゴルーチンが対話するために使用する導管に例えることができるかもしれません。
チャネルとは?
2つのゴルーチンはチャネルを介して相互に作用し、その動作を調整することができます。本ソフトウェアでは、"ping"と連続的に表示されます。チャンネルの形式を指定するには、"chan"という接頭語に、チャンネルで伝送される項目をつけます。"この場合、文字列を提供することになります。チャネルでは、演算子を用いてメッセージを送受信します。"ping" は、"ping" を送信することを指します。
チャネルは、2つのゴルーチンの同期を保つために使用されます。ルーターはチャンネルを越えてメッセージを送信しようとする前に、プリンターがメッセージを受け入れる準備ができるまで待ちます。これをインヒビションといいます。チャネルを作成する場合、make関数に第2パラメータを使用することができます。c:= make (chan int, 1)
チャネルの方向
チャネルのフォームの向きを定義し、それを受信または送信のいずれかにパラメータ化することができます。例えばPingerのメソッド記号は、このように変更することができます。
func pinger(c chan<- string)
Cは今しか送れません。cから受信すると、コードエラーになります。同様に、出力を次のように変更することもできます。
func printer(c string -chan)
半チャンネルはこのような制約がありません。送信専用や受信専用のチャネルしか受け付けない手続きに対して、双方向のチャネルを与えることはできますが、その逆はできません。
ゴルーチンの作り方
ゴルーチンの起動方法は簡単です。関数呼び出しに "go" キーワードを適用して、同時実行するゴルーチンを作ります。ここでは、ゴルーチンを作ることにします。例えば、ウェルカム関数とメイン関数の2つの関数からなるプログラムがあるとします。
新しいゴルーチンを作ると、welcome()のコードはmain()関数と並行して実行されます。このプログラムを実行すると、驚かれることでしょう。このプログラムは単にmainの動作テキストを表示しているだけです。最初に起動したゴルーチンや新しいゴルーチンはどうなったのでしょうか?その理由を理解するためには、まず、ゴルーチンの2大特徴を知る必要があります。
- ゴルーチン関数は、新しいゴルーチンを作ると即座に反応する。関数は別として、管理側はゴルーチンに依存しないので、ゴルーチンの実行が完了するのを待つことはない。実行は、ゴルーチン関数の次のコードブロックに渡されます。このため、ゴルーチンから与えられたパラメータは無視されます。
- 余分なゴルーチンは、主ゴルーチンと同時に実行されるべきです。もし、主ゴルーチンが失敗したら、プログラムは終了し、追加のゴルーチンは実行されません。
これで、今回のコードがうまくいかなかった理由がわかったと思います。go welcome() の呼び出しに続いて、hello ゴルーチンの完了を待つ前に次のコード行に制御が移され、main 関数が出力されました。実行するスクリプトがないため、mainゴルーチンが死亡し、helloゴルーチンの実行を妨げた。
スリープ技法(time.sleep(1 * time.second))を発動して、ゴルーチンを1秒間停止させました。これで、goelcome()する関数は、メインゴルーチンが終了する前に十分な時間を確保することができました。このソフトは、最初に"welcome goroutine"を書き、1秒待ってからmain関数を表示します。主ゴルーチンのスリープ技法を使って、他のゴルーチンが完了するまでの間、一時停止しているのです。
複数作成するGoroutines
複数のゴルーチンを作成するために、別のプログラムを起動することにします。まず、並列に実行される2つのゴルーチンを作成することから始めます。この2つのゴルーチンは数字ゴルーチン[go numbers()]とアルファベットゴルーチン[go alphabets () ]です。
数字ゴルーチンは1を出力する前に250ms滞在し、2を出力する前に再び休憩し、5を出力するまで続けます。同様に、英数字ゴルーチンは、aからeまでの文字を表示した後、400ミリ秒待ちます。最後に、主ゴルーチンが整数と英数字を作成し、一回休止した後、主ゴルーチンが終了する。
並行プログラミングのよくある間違い
- これが必要なときに同期を取らないこと
- 時間を使う。同期をとるためにSleepコールを使う
- 標準的な同期パッケージの型のコピー値をゴルーチンがぶら下がったままにする
- 同期を呼び出す
- 待機グループ
- 間違った場所にメソッドを追加する
- チャンネルは最後の関数送信者ゴルーチンからではなく、明日のクローズチャンネルとして使用します。
まとめ
今回は、go キーワードを使用して、1 つのゴルーチンと複数のゴルーチンを起動し、同時に整数を出力するプログラムを開発しました。プログラムを起動した後、新しいチャネルを確立し、そのチャネルを使ってあるゴルーチンで数値を生成し、別のゴルーチンに渡して画面に表示することができました。マルチコアシステムでアプリケーションを高速化するためのゴルーチンの起動方法の最後のデモンストレーションとして、同時に多くの「印刷」ゴルーチンを起動しました。
ご存知のように、ゴルーチンはタスクをより速く、効率的に実行するための方法です。これは、AppMaster が提供する、アプリケーションの機能性を向上させるための展開手順の1つです。AppMaster を使えば、プログラミングの知識がほとんどない人でも、マニュアル・コーディングでは困難な作業を完了させることができます。
AppMaster は no-codeは、モバイルやウェブアプリケーション 、バックエンドを作成 することができるプラットフォームです。興味深いことに、AppMaster は、Go によってバックエンドを毎秒22,000行で作成し、ソースコードにアクセスすることができます。