目錄
1.並發簡介
並發是同時處理多個任務的能力。在 Go 中,並發性是一等公民,內建於該語言的核心設計中。 Go 的並發方法是基於通訊順序進程(CSP),該模型強調進程之間的通訊而不是共享記憶體。
2.併發與並行:
Go 例程支援並發,並發是獨立執行進程的組合。
如果系統有多個 CPU 核心並且 Go 運行時安排 go 例程並行運行,則可能會發生並行(同時執行)。
3。 Go 例程:
並發的構建塊是 Go 例程是由 Go 運行時管理的輕量級執行緒。它是與其他函數或方法同時運行的函數或方法。 Go 例程是 Go 並發模型的基礎。
主要特徵:
建立 Go 程式:
要啟動 go 例程,只需使用 go 關鍵字,後面接著函數呼叫:
go functionName()
或使用匿名函數:
go func() { // function body }()
Go-routine 調度:
通訊與同步:
範例及說明:
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") }
說明:
Goroutine 生命週期:
最佳實務:
帶有 go 程式解釋的簡單範例
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 例程提供了一種將資料傳送到另一個 go 例程的方法。
頻道的目的
Go 中的通道有兩個主要用途:
a) 通訊:它們允許 goroutine 相互發送和接收值。
b) 同步:它們可用於跨 Goroutine 同步執行。
建立:使用 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中文網其他相關文章!