五 Golang併發程式設計與同步機制 死鎖與條件變數

2021-10-18 21:12:03 字數 2630 閱讀 3575

1. 單go程自己死鎖

channel 應該在 至少 2 個以上的 go程中進行通訊。否則死鎖!!!

func

main()

2.go程間channel訪問順序導致死鎖

使用channel一端讀(寫), 要保證另一端寫(讀)操作,同時有機會執行。否則死鎖。

func

main()

()num :=

<- ch //主go程直接結束

fmt.

println

("num = "

, num)

}3. 多go程,多channel 交叉死鎖

ago程,掌握m的同時,嘗試拿n; bgo程,掌握n的同時嘗試拿m。

func

main()

}}()

for}

}4. 在go語言中,盡量不要將 互斥鎖、讀寫鎖 與 channel 混用。 —— 隱性死鎖。

a 、b go程 共同訪問共享資料。 由於cpu排程隨機,需要對 共享資料訪問順序加以限定(同步)。

建立 mutex(互斥鎖),訪問共享資料之前,加鎖,訪問結束,解鎖。 在ago程加鎖期間,b go程加鎖會失敗——阻塞。

直至 a go程 解鎖mutex,b 從阻塞處。恢復執行。

var mutex sync.mutex // 建立乙個互斥量, 新建的互斥鎖狀態為 0. 未加鎖。 鎖只有一把。

func

printer

(str string

) mutex.

unlock()

// 共享資料訪問結束,解鎖

}func

person1()

func

person2()

func

main()

}

讀時共享,寫時獨佔。寫鎖優先順序比讀鎖高。
//rwlock實現

var rwmutex sync.rwmutex // 鎖只有一把, 2 個屬性 r w

var value int

// 定義全域性變數,模擬共享資料

func

readgo05

(idx int)}

func

writego05

(idx int)}

func

main()

for i:=

0; i<

5; i++

for}

//channel實現

func

readgo06

(in <-

chan

int, idx int)}

func

writego06

(out chan

<-

int, idx int)}

func

main()

for i:=

0; i<

5; i++

for}

本身不是鎖!!! 但經常與鎖結合使用!!

使用流程:

1. 建立 條件變數: var cond sync.cond

2. 指定條件變數用的 鎖: cond.l =

new(sync.mutex)

3. cond.l.

lock

() 給公共區加鎖(互斥量)

4. 判斷是否到達 阻塞條件(緩衝區滿/空) —— for 迴圈判斷

forlen(ch)

==cap

(ch)

num := rand.

intn

(800

) out <- num

fmt.

printf

("生產者%dth,生產:%d\n"

, idx, num)

// 訪問公共區結束,並且列印結束,解鎖

cond.l.

unlock()

// 喚醒阻塞在條件變數上的 消費者

cond.

signal()

time.

sleep

(time.millisecond *

200)}}

func

consumer08

(in <-

chan

int, idx int

) num :=

<-in

fmt.

printf

("-----消費者%dth,消費:%d\n"

,idx, num)

// 訪問公共區結束後,解鎖

cond.l.

unlock()

// 喚醒 阻塞在條件變數上的 生產者

cond.

signal()

time.

sleep

(time.millisecond *

200)}}

func

main()

for i:=

0; i<

5; i++

/* for */

<-quit

}

併發程式設計之同步機制(一) Semphore訊號量

本文的目的是要分析訊號量內部的實現流程,不深入訊號量底層的實現細節aqs 將會有另外一篇文章分析 讓讀者能夠理解訊號量內部結構和呼叫流程。semaphore 內部持有一系列的許可 permit acquire操作會被阻塞直到有足夠多的許可可用,最後會占用這些許可 release操作會歸還許可讓阻塞的...

Go 語言程式設計 併發 同步原語與鎖

協程鎖主要用於保證在執行 goroutine 的時候不阻塞 m。舉例 任務 a 需要修改 z,任務 b 也需要修改 z。如果是序列系統,a 執行完了,再執行b,很簡單。在併發系統中,因為 a,b 是併發執行的,所以就需要在操作 z 的時候確保 a b 保證序列化的機制。a 要修改 z,所以 a 加了...

高效能網路程式設計(五) IO復用與併發程式設計

對於伺服器的併發處理能力,我們需要的是 每一毫秒伺服器都能及時處理這一毫秒內收到的數百個不同tcp連線上的報文,與此同時,可能伺服器上還有數以十萬計的最近幾秒沒有收發任何報文的相對不活躍連線。同時處理多個並行發生事件的連線,簡稱為併發 同時處理萬計 十萬計的連線,則是高併發。伺服器的併發程式設計所追...