目次
1.並行性の概要
同時実行性とは、複数のタスクを同時に処理できる機能です。 Go では、同時実行性は第一級の要素であり、言語のコア設計に組み込まれています。 Go の同時実行性へのアプローチは、共有メモリではなくプロセス間の通信を重視するモデルである Communicating Sequential Processes (CSP) に基づいています。
2.同時実行性と並列性:
Go ルーチンにより、独立して実行されるプロセスの構成である並行性が可能になります。
システムに複数の CPU コアがあり、Go ランタイムが go ルーチンを並列実行するようにスケジュールしている場合、並列処理 (同時実行) が発生する可能性があります。
3.ゴールーチン:
同時実行の構成要素は Go ルーチンであり、Go ランタイムによって管理される軽量のスレッドです。これは、他の関数またはメソッドと同時に実行される関数またはメソッドです。 Go ルーチンは Go の同時実行モデルの基礎です。
主な特徴:
ゴールーチンの作成:
go ルーチンを開始するには、go キーワードに続いて関数呼び出しを使用するだけです:
go functionName()
または匿名関数を使用します:
go func() { // function body }()
通常のスケジュール:
通信と同期:
説明付きの例:
package main import ( "fmt" "time" ) func printNumbers() { for i := 1; i <= 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Printf("%d ", i) } } func printLetters() { for i := 'a'; i <= 'e'; i++ { time.Sleep(150 * time.Millisecond) fmt.Printf("%c ", i) } } func main() { go printNumbers() go printLetters() time.Sleep(2 * time.Second) fmt.Println("\nMain function finished") }
説明:
ゴルーチンのライフサイクル:
ベストプラクティス:
ゴールーチンの説明を含む簡単な例
package main import ( "fmt" "time" ) // printNumbers is a function that prints numbers from 1 to 5 // It will be run as a goroutine func printNumbers() { for i := 1; i <= 5; i++ { time.Sleep(500 * time.Millisecond) // Sleep for 500ms to simulate work fmt.Printf("%d ", i) } } // printLetters is a function that prints letters from 'a' to 'e' // It will also be run as a goroutine func printLetters() { for i := 'a'; i <= 'e'; i++ { time.Sleep(300 * time.Millisecond) // Sleep for 300ms to simulate work fmt.Printf("%c ", i) } } func main() { // Start printNumbers as a goroutine // The 'go' keyword before the function call creates a new goroutine go printNumbers() // Start printLetters as another goroutine go printLetters() // Sleep for 3 seconds to allow goroutines to finish // This is a simple way to wait, but not ideal for production code time.Sleep(3 * time.Second) // Print a newline for better formatting fmt.Println("\nMain function finished") }
4.チャンネル:
チャネルは、Go ルーチンが相互に通信し、実行を同期できるようにする Go の中核機能です。これらは、ある go-routine が別の go-routine にデータを送信する方法を提供します。
チャンネルの目的
Go のチャネルは 2 つの主な目的を果たします:
a) 通信: ゴルーチンが相互に値を送受信できるようにします。
b) 同期: ゴルーチン間で実行を同期するために使用できます。
作成: チャンネルは make 関数を使用して作成されます:
ch := make(chan int) // Unbuffered channel of integers
送信: <- 演算子を使用して値がチャネルに送信されます:
ch <- 42 // Send the value 42 to the channel
Receiving: Values are received from a channel using the <- operator:
value := <-ch // Receive a value from the channel
Types of Channels
a) Unbuffered Channels:
ch := make(chan int) go func() { ch <- 42 // This will block until the value is received }() value := <-ch // This will receive the value
b) Buffered Channels:
ch := make(chan int, 2) ch <- 1 // Doesn't block ch <- 2 // Doesn't block ch <- 3 // This will block until a value is received
Channel Directions
Channels can be directional or bidirectional:
Example :
func send(ch chan<- int) { ch <- 42 } func receive(ch <-chan int) { value := <-ch fmt.Println(value) }
Closing Channels
Channels can be closed to signal that no more values will be sent:
close(ch)
Receiving from a closed channel:
If the channel is empty, it returns the zero value of the channel's type.
You can check if a channel is closed using a two-value receive:
value, ok := <-ch if !ok { fmt.Println("Channel is closed") }
Ranging over Channels
You can use a for range loop to receive values from a channel until it's closed:
for value := range ch { fmt.Println(value) }
Hey, Thank you for staying until the end! I appreciate you being valuable reader and learner. Please follow me here and also on my Linkedin and GitHub .
以上がGo の同時実行性: 基本から高度な概念までの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。