golang并發(fā)編程中Goroutine 協(xié)程的實現(xiàn)
Go 協(xié)程(Goroutine)是 Go 語言提供的一種輕量級線程,由 Go 運行時來管理。是與其他函數同時運行的函數,它們是并發(fā)執(zhí)行代碼的基礎。
在函數調用前加上 go 關鍵字,這次調用就會在一個新的 goroutine 中并發(fā)執(zhí)行。當被調用的函數返回時,這個 goroutine 也自動結束。
需要注意的是,如果這個函數有返回值,那么這個返回值會被丟棄。
Go 協(xié)程(Goroutine)之間通過通道(channel)進行通信,簡單的說就是多個協(xié)程之間通信的管道。通道可以防止多個協(xié)程訪問共享內存時發(fā)生資源爭搶的問題。
啟動 Goroutine
要啟動一個新的 Goroutine,只需要在函數調用前加上 go 關鍵字。例如:
這行代碼會啟動一個新的 Goroutine 來執(zhí)行 myFunction。
Goroutine 的特性
- 輕量級:Goroutine 比傳統(tǒng)線程更輕量級。每個 Goroutine 使用的內存非常少,啟動速度也更快。
- 調度:Goroutine 由 Go 運行時管理和調度,而不是操作系統(tǒng)。
- 棧管理:Goroutine 的棧是動態(tài)增長的,初始大小一般較?。ㄈ?2KB),但可以根據需要動態(tài)擴展,最大可達 1GB。
同步和通信
在 Go 中,同步和通信通常通過通道(channel)來實現(xiàn)。通道是 Go 語言提供的一種類型安全的通信機制。
創(chuàng)建通道
可以使用 make 函數創(chuàng)建通道:
發(fā)送和接收
使用 <- 操作符可以發(fā)送和接收數據:
// 發(fā)送數據到通道 ch <- 42 // 從通道接收數據 value := <-ch
帶緩沖的通道
創(chuàng)建帶緩沖的通道:
ch := make(chan int, 100)
這樣通道可以在不阻塞發(fā)送 Goroutine 的情況下緩沖一定數量的數據。
示例代碼
以下是一個簡單的 Goroutine 和通道的示例:
package main
import (
"fmt"
"time"
)
func worker(ch chan int) {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(time.Second)
}
close(ch)
}
func main() {
ch := make(chan int)
go worker(ch)
for val := range ch {
fmt.Println(val)
}
}
在這個例子中,worker 函數向通道 ch 發(fā)送數據,然后 main 函數從通道 ch 接收數據并打印。
Goroutines 和主程序
需要注意的是,如果主程序退出,所有未完成的 Goroutines 也會立即終止。因此,通常需要確保主程序等待所有 Goroutines 完成。例如,可以使用 sync.WaitGroup 來實現(xiàn)這一點:
package main
import (
"fmt"
"sync"
)
func worker(wg *sync.WaitGroup, id int) {
defer wg.Done()
fmt.Printf("Worker %d starting\n", id)
// 模擬工作
time.Sleep(time.Second)
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(&wg, i)
}
wg.Wait()
fmt.Println("All workers done")
}
這個示例使用 sync.WaitGroup 來等待所有的 Goroutines 完成。wg.Add(1) 用于增加計數,wg.Done() 在 Goroutine 完成時減少計數,wg.Wait() 則阻塞直到所有的 Goroutines 完成。
協(xié)程、線程、進程
協(xié)程、線程和進程是并發(fā)和并行編程中的三種主要概念。它們有不同的特性和適用場景,以下是它們的主要區(qū)別:
進程 (Process)
定義:
- 進程是操作系統(tǒng)中資源分配的基本單位。
- 每個進程都有自己的內存空間、文件描述符和其他資源。
特點:
- 隔離性:進程之間是相互獨立的,一個進程的崩潰不會影響其他進程。
- 開銷大:進程之間切換的開銷較大,需要保存和恢復大量上下文信息。
- 通信復雜:進程間通信(IPC,如管道、消息隊列、共享內存等)相對復雜。
適用場景:
- 適用于需要高度隔離和獨立運行的任務。
- 適用于不同編程語言和不同平臺之間的并發(fā)處理。
線程 (Thread)
定義:
- 線程是進程中的一個執(zhí)行單元,屬于進程的一部分。
- 同一進程中的線程共享該進程的內存和其他資源。
特點:
- 輕量級:相比進程,線程的創(chuàng)建和切換開銷較小。
- 共享資源:同一進程內的線程可以直接訪問共享的內存和資源,但也因此帶來了同步問題。
- 并發(fā)執(zhí)行:多個線程可以在多核 CPU 上并發(fā)執(zhí)行。
適用場景:
- 適用于需要并行處理的任務,如多線程服務器、并行計算等。
- 適用于需要頻繁切換和低開銷的場景。
協(xié)程 (Coroutine)
定義:
- 協(xié)程是一種用戶態(tài)的輕量級線程,也稱為微線程或纖程。
- 協(xié)程由程序自身管理調度,而不是操作系統(tǒng)。
特點:
- 更輕量級:協(xié)程的創(chuàng)建和切換開銷更小,因為不涉及內核態(tài)的切換。
- 協(xié)作式調度:協(xié)程通過顯式的讓出操作(如
yield)來切換,控制權由程序員掌握。 - 共享內存:同一線程內的協(xié)程可以共享內存,但需要注意同步問題。
適用場景:
- 適用于 I/O 密集型任務,如高并發(fā)網絡服務器。
- 適用于需要大量并發(fā)但對并行性要求不高的場景,如爬蟲、異步編程等。
總結
- 進程:資源隔離好,開銷大,適用于獨立運行的任務。
- 線程:資源共享,開銷較小,適用于需要并行處理的任務。
- 協(xié)程:更輕量級,用戶態(tài)調度,適用于大量并發(fā)的 I/O 密集型任務。
各自的選擇主要取決于具體的應用場景和性能需求。協(xié)程在現(xiàn)代編程中越來越受歡迎,尤其是在需要高并發(fā)和高效 I/O 操作的場景中。
到此這篇關于golang并發(fā)編程中Goroutine 協(xié)程的實現(xiàn)的文章就介紹到這了,更多相關golang Goroutine 協(xié)程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- golang gin 框架 異步同步 goroutine 并發(fā)操作
- Go語言中的并發(fā)goroutine底層原理
- Go并發(fā)編程之goroutine使用正確方法
- Go 并發(fā)編程Goroutine的實現(xiàn)示例
- Golang 語言控制并發(fā) Goroutine的方法
- Go中Goroutines輕量級并發(fā)的特性及效率探究
- 使用Go?goroutine實現(xiàn)并發(fā)的Clock服務
- Go語言使用goroutine及通道實現(xiàn)并發(fā)詳解
- Go 控制協(xié)程(goroutine)的并發(fā)數量
- Go語言使用Goroutine并發(fā)打印的項目實踐
相關文章
Golang如何編寫內存高效及CPU調優(yōu)的Go結構體
這篇文章主要介紹了Golang如何編寫內存高效及CPU調優(yōu)的Go結構體,結構體是包含多個字段的集合類型,用于將數據組合為記錄2022-07-07

