首頁 後端開發 Golang go語言中的並發介紹(附程式碼)

go語言中的並發介紹(附程式碼)

Nov 25, 2019 pm 02:49 PM
go 並行

go語言中的並發介紹(附程式碼)

當被問到為什麼用Go語言,一定不得不提的是Go語言的並發程式編寫。在C語言中編寫非常繁瑣複雜的並發程式在Go語言中總是顯得如此便捷。

Go中並發程式依賴的是兩個:goroutine和channel

#理解什麼是goroutine?

##對於初學者,goroutine直接理解成為線程就可以了。當對一個函數呼叫go,啟動一個goroutine的時候,就相當於起來一個線程,執行這個函數。

實際上,一個goroutine並不相當於一個線程,goroutine的出現正是為了替代原來的線程概念成為最小的調度單位。

一旦執行goroutine時,先去當先線程查找,如果線程阻塞了,則被分配到空閒的線程,如果沒有空閒的線程,那麼就會新建一個線程。注意的是,當goroutine執行完畢後,線程不會回收推出,而是成為了空閒的線程。

goroutine的使用

使用非常簡單,在函數前面增加一個go

f(11)

go f(11) //這個是讓f()函數當作goroutine運行

但是go有一個缺點,主執行緒要等待一個goroutine結束再處理怎麼辦?拿《學習go語言》中的一個例子來說明。

go語言中的並發介紹(附程式碼)

這裡的第18行為什麼要sleep?這裡是為了等上面兩個go ready處理完成。

好了,這裡就出來了一個需求:一個goroutine結束後必須要向主線程傳輸數據,告訴主線程這個goroutine已經結束了。

這裡就引進了channel的概念

channel的使用

channel的意思用白話可以這麼理解:主線程告訴大家你開goroutine可以,但是我在我的主線程開了一個管道,你做完了你要做的事情之後,往管道裡面塞個東西告訴我你已經完成了。

上面的範例就可以改為:

go語言中的並發介紹(附程式碼)

從這個程式得到的幾點訊息:

1 channel只能使用make來進行建立

基本格式是c := make(chan int)

int是說明這個管道能傳送什麼類型的資料

2 往channel插入資料的操作

c #是不是很形象

##3 從channel輸出資料

4 為什麼需要輸出兩次(4和5兩行?)

因為2和3啟動了兩個goroutine,每個goroutine都往管道輸出一個1,因此主線程要接收兩次才能說明兩個goroutine都結束了

channel的進一步理解:channel分為兩種:一種是有buffer的,一種是沒有buffer的,預設是沒有buffer的

ci := make(chan int) //無buffer

cj := make(chan int, 0) //無buffer

cs := make(chan int, 100) //有buffer

#有緩衝的channel ,因此要注意「放」先於「取」

無緩衝的channel,因此要注意「取」先於「放」

同樣要先輸出hello world,使用有緩衝的channel和無緩衝的channel分別是這樣的:

有緩衝的channel:

var a string
var c = make(chan int, 10)
  
func f() {
    a = "hello, world"
    c <- 0
}
  
func main() {
    go f()
    <-c
    print(a)
 
}
登入後複製
這裡有個緩衝,因此放入資料的操作c<- 0先於取資料運算<-c

無緩衝的channel:

var a string
var c = make(chan int)
  
func f() {
    a = "hello, world"
    <-c
}
  
func main() {
    go f()
    c <- 0
    print(a)
 
}
登入後複製
由於c是無緩衝的channel,因此必須保證取操作

推薦:

golang教學

欄位

以上是go語言中的並發介紹(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Go WebSocket 訊息如何發送? Go WebSocket 訊息如何發送? Jun 03, 2024 pm 04:53 PM

在Go中,可以使用gorilla/websocket包發送WebSocket訊息。具體步驟:建立WebSocket連線。傳送文字訊息:呼叫WriteMessage(websocket.TextMessage,[]byte("訊息"))。發送二進位訊息:呼叫WriteMessage(websocket.BinaryMessage,[]byte{1,2,3})。

並發和協程在Golang API設計中的應用 並發和協程在Golang API設計中的應用 May 07, 2024 pm 06:51 PM

並發和協程在GoAPI設計中可用於:高效能處理:同時處理多個請求以提高效能。非同步處理:使用協程非同步處理任務(例如傳送電子郵件),釋放主執行緒。流處理:使用協程高效處理資料流(例如資料庫讀取)。

Golang 與 Go 語言的區別 Golang 與 Go 語言的區別 May 31, 2024 pm 08:10 PM

Go和Go語言是不同的實體,具有不同的特性。 Go(又稱Golang)以其並發性、編譯速度快、記憶體管理和跨平台優點而聞名。 Go語言的缺點包括生態系統不如其他語言豐富、文法更嚴格、缺乏動態類型。

如何在 Go 中使用正規表示式匹配時間戳記? 如何在 Go 中使用正規表示式匹配時間戳記? Jun 02, 2024 am 09:00 AM

在Go中,可以使用正規表示式比對時間戳記:編譯正規表示式字串,例如用於匹配ISO8601時間戳記的表達式:^\d{4}-\d{2}-\d{2}T \d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$ 。使用regexp.MatchString函數檢查字串是否與正規表示式相符。

Golang 技術效能優化中如何避免記憶體洩漏? Golang 技術效能優化中如何避免記憶體洩漏? Jun 04, 2024 pm 12:27 PM

記憶體洩漏會導致Go程式記憶體不斷增加,可通過:關閉不再使用的資源,如檔案、網路連線和資料庫連線。使用弱引用防止記憶體洩漏,當物件不再被強引用時將其作為垃圾回收目標。利用go協程,協程棧記憶體會在退出時自動釋放,避免記憶體洩漏。

Golang 函數接收 map 參數時的注意事項 Golang 函數接收 map 參數時的注意事項 Jun 04, 2024 am 10:31 AM

在Go中傳遞map給函數時,預設會建立副本,對副本的修改不影響原map。如果需要修改原始map,可透過指標傳遞。空map需小心處理,因為技術上是nil指針,傳遞空map給期望非空map的函數會發生錯誤。

如何使用 Golang 的錯誤包裝器? 如何使用 Golang 的錯誤包裝器? Jun 03, 2024 pm 04:08 PM

在Golang中,錯誤包裝器允許你在原始錯誤上追加上下文訊息,從而創建新錯誤。這可用於統一不同程式庫或元件拋出的錯誤類型,簡化偵錯和錯誤處理。步驟如下:使用errors.Wrap函數將原有錯誤包裝成新錯誤。新錯誤包含原始錯誤的上下文資訊。使用fmt.Printf輸出包裝後的錯誤,提供更多上下文和可操作性。在處理不同類型的錯誤時,使用errors.Wrap函數統一錯誤類型。

Go 並發函數的單元測試指南 Go 並發函數的單元測試指南 May 03, 2024 am 10:54 AM

對並發函數進行單元測試至關重要,因為這有助於確保其在並發環境中的正確行為。測試並發函數時必須考慮互斥、同步和隔離等基本原理。可以透過模擬、測試競爭條件和驗證結果等方法對並發函數進行單元測試。

See all articles