Go 語言并發編程介紹
- Goroutine
定義:Goroutine 是 Go 語言中的輕量級線程,由 Go 運行時管理。
創建:使用 go 關鍵字啟動一個新的 Goroutine。
示例:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
- Channel
定義:Channel 是 Goroutine 之間通信的管道,用于在不同的 Goroutine 之間傳遞數據。
創建:使用 make 函數創建 Channel。
類型:Channel 可以是單向的(只能發送或接收)或雙向的(可以發送和接收)。
示例:
import (
"fmt"
)
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 將結果發送到 Channel
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 從 Channel 接收結果
fmt.Println(x, y, x+y)
}
- 同步原語
WaitGroup:用于等待多個 Goroutine 完成。
Mutex:用于保護共享資源的互斥鎖。
示例:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
var mu sync.Mutex
var counter int
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
mu.Lock()
counter++
mu.Unlock()
}()
}
wg.Wait()
fmt.Println("Counter:", counter)
}
- 選擇語句(Select)
定義:select 語句用于在多個 Channel 操作之間進行選擇。
示例:
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("Received:", msg1)
case msg2 := <-c2:
fmt.Println("Received:", msg2)
}
}
}
- 上下文(Context)
定義:Context 用于在 Goroutine 之間傳遞請求范圍的值、取消信號等。
示例:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
done := make(chan bool, 1)
go func(ctx context.Context) {
select {
case <-ctx.Done():
fmt.Println("Context canceled:", ctx.Err())
done <- true
case <-time.After(2 * time.Second):
fmt.Println("Task completed")
done <- true
}
}(ctx)
<-done
}