Golang は効率的で高速かつ安全性の高い言語であり、その同時実行機能により、ますます人気があり強力なツールとなっています。この記事では、基本的な概念から始めて、Golang が同時実行性を実装する方法を紹介します。
1. 同時実行と並列処理
最初に明確にする必要があるのは、同時実行と並列処理の違いです。並行性とは、複数のタスクが重複して同じ期間に実行されることを指し、並列性とは、複数のタスクが同時に実行されることを指します。実際にはこの 2 つを混同することがよくありますが、理論的にはまったく異なる概念です。
2. Golang の goroutine
Golang の同時実行性は主に goroutine に依存します。 Goroutine は、go キーワードによって開始される Golang の軽量スレッドです。 goroutine とスレッドの最大の違いは、実行時にオペレーティング システムのスレッドに依存せず、Golang のランタイム システムによって直接管理されることです。各 goroutine は、Go 言語実行環境 (ランタイム) によってスケジュールされた独立したユニットであり、論理プロセッサで実行されます。論理プロセッサは、オペレーティング システムの実際のスレッド数に対する goroutine の割り当てを決定します。
Golang プログラムでは、main 関数はデフォルトで goroutine 内で実行され、他の goroutine はいつでも開始でき、main 関数または他の goroutine と同時に実行できます。
3. go キーワードを使用して goroutine を開始します
go キーワードを使用して goroutine を簡単に開始します。関数呼び出しの前にキーワード go を追加するだけで、システムは必要に応じて新しい goroutine を自動的に開きます。例:
go func1(arg1, arg2)
このステートメントは、 goroutine の形式で func1 関数を実行し、同期コードは引き続き実行されます。このとき、プログラムは最初にこのステートメントを出力し、すぐに次のコードを実行します。特定の時点で、Go 言語ランタイムは関数を実行するための新しい goroutine を開始します。この場合、ゴルーチンがいつ開始され、いつ終了するかを直接知ることはできません。
戻り値を持つ関数の場合、次のステップに進む前にゴルーチンの実行が完了するまで待つ必要がありますが、このプロセスはチャネルを使用して実現できます。
4. チャネル
チャネルは、Golang 同時プログラミングにおける非常に重要な通信メカニズムです。チャネルを使用すると、ゴルーチン間のデータ交換が可能になります。チャネルには常に送信操作と受信操作があり、デフォルトでは相手側の準備が整うまでブロックされます。
チャネルを作成するための構文は次のとおりです。
channel := make(chan type)
ここで、type には任意のタイプを指定でき、チャネルは type のパイプです。
データをチャネルに送信するための構文は次のとおりです。
channel <- data
このステートメントはデータをチャネルに送信し、データの受信を待機しているゴルーチンに送信します。
ゴルーチンでチャネルからデータを受信するための構文は次のとおりです。
data := <- channel
このステートメントはチャネルからデータを受信します。チャネルにデータがない場合、このステートメントはデータの到着の待機をブロックします。
チャネルを通じて、ゴルーチン間の同期と同時実行性を制御できます。例:
ch := make(chan int) go func(){ ch <- 1 }() data := <- ch
このステートメントは、新しい goroutine の開始後に goroutine がチャネルにデータを送信するまで待機し、チャネルからデータを受信して実行を継続します。
5. 同期パッケージ
チャネルに加えて、Golang は同時プログラミングをサポートするための Sync パッケージも提供します。このパッケージは、ミューテックス ロックなどの多くのアトミック操作機能とメカニズムを提供します。
アトミック操作関数は、Golang 同時プログラミングにおいて非常に重要な概念です。これにより、実行中に一連の操作が不可分であることが保証されます。つまり、アトミック操作を実行するときに、他のゴルーチンは中間状態を見ることができません。 、オブジェクトは変更されていないか、変更されています。これにより、同期の問題は非常にうまく解決できます。
例:
var sum int64 = 0 for i := 0; i < 10000; i++ { go func(){ atomic.AddInt64(&sum, 1) }() }
このステートメントは、計算にアトミック操作関数を使用する方法を示しています。このプログラムでは、ゴルーチンは競合状態を引き起こすことなく sum 変数に 1 を継続的に加算します。変数の読み取りと書き込みの同期の欠如によって引き起こされるこの問題は競合状態と呼ばれますが、アトミック操作関数はこの問題を完全に回避できます。
6. 概要
この記事では、Golang が同時実行性を実装する方法を紹介します。主に、Golang のゴルーチン、チャネル、Sync パッケージのアトミック操作などの基本要素と、同時プログラミングにおけるそれらのアプリケーションについて説明します。 Golang の同時実行機能は、エンジニアリング タスクの処理、サーバーの同時処理、リアルタイム システム開発などの多くの分野で役立つだけでなく、Golang が人気のプログラミング言語になった重要な理由の 1 つでもあります。
以上がGolangで同時実行を行う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。