Go語言學習之Go協程(goroutine)


介紹

說到Go語言,很多沒接觸過它的人,對它的第一印象,一定是它從語言層面天生支持並發,非常方便,讓開發者能快速寫出高性能且易於理解的程序。

在 Python (為Py為例,主要是我比較熟悉,其他主流編程語言也類似)中,並發編程的門檻並不低,你要學習多進程,多線程,還要掌握各種支持並發的庫 asyncio,aiohttp 等,同時你還要清楚它們之間的區別及優缺點,懂得在不同的場景選擇不同的並發模式。

而 Golang 作為一門現代化的編程語言,它不需要你直面這些復雜的問題。在 Golang 里,你不需要學習如何創建進程池/線程池,也不需要知道什么情況下使用多線程,什么時候使用多進程。因為你沒得選,也不需要選,它原生提供的 goroutine (也即協程)已經足夠優秀,能夠自動幫你處理好所有的事情,而你要做的只是執行它,就這么簡單。

一個 goroutine 本身就是一個函數,當你直接調用時,它就是一個普通函數,如果你在調用前加一個關鍵字 go ,那你就開啟了一個 goroutine

// 執行一個函數
func()

// 開啟一個協程執行這個函數
go func()

1.協程的初步使用

一個Go程序的入口通常是main,程序啟動后,main函數最先運行,我們稱之為main goroutine

在main中或者其下調用的代碼中才可以使用go + func()的方法來啟動協程

main的地位相當於主線程,當main函數執行完成后,這個線程也就終結了,其下運行着的所有協程也不管代碼是不是還在跑,也得乖乖退出

 

因此如下代碼運行完,只會輸出hello,world,而不會輸出hello,go(因為協程的創建需要時間,當hello,world打印后,協程還沒來得及創建並執行)

import "fmt"

func mytest() {
    fmt.Println("hello, go")
}

func main() {
    // 啟動一個協程
    go mytest()
    fmt.Println("hello, world")
}

 

對於剛學習Go的協程的人來說,可以使用time.Sleep來是main阻塞,使其他協程能夠有機會運行完全,但你要注意的是 這並不是推薦的方式

當我在代碼里加入一行time.Sleep輸出就符合預期了

import (
    "fmt"
    "time"
)

func mytest() {
    fmt.Println("hello, go")
}

func main() {
    go mytest()
    fmt.Println("hello, world")
    time.Sleep(time.Second)
}

輸出如下

hello, world
hello, go

2.多個協程的效果

為了看到並發效果,這里舉個最簡單的例子

import (
    "fmt"
    "time"
)

func mygo(name string) {
    for i := 0; i < 10; i++ {
        fmt.Printf("In goroutine %s\n", name)
        // 為了避免第一個協程執行過快,觀察不到並發的效果,加個休眠
        time.Sleep(10 * time.Millisecond) 
    }
}

func main() {
    go mygo("協程1號") // 第一個協程
    go mygo("協程2號") // 第二個協程
    time.Sleep(time.Second)
}

輸出如下,可以觀察到兩個協程就如兩個線程一樣,並發執行

In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程2號
In goroutine 協程1號
In goroutine 協程2號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM