條件變數:共享資料的狀態發生變化時,通知阻塞在某個條件上的協程(執行緒)
條件變數是乙個結構體,cond.l要搭配鎖一起使用
type cond struct
三個常用方法:
func (c *cond) wait()
a) 阻塞等待條件變數滿足
b) 釋放已掌握的互斥鎖相當於cond.l.unlock()。 注意:兩步為乙個原子操作。
c) 當被喚醒,wait()函式返回時,解除阻塞並重新獲取互斥鎖。相當於cond.l.lock()
func (c *cond) signal()
package main
import
"fmt"
import
"sync"
import
"math/rand"
import
"time"
var cond sync.cond // 建立全域性條件變數
// 生產者
func
producer
(out chan
<-
int, idx int
) num := rand.
intn
(1000
)// 產生乙個隨機數
out <- num // 寫入到 channel 中 (生產)
fmt.
printf
("%dth 生產者,產生資料 %3d, 公共區剩餘%d\n"
, idx, num,
len(out)
) cond.l.
unlock()
// 生產結束,解除互斥鎖
cond.
signal()
// 喚醒 阻塞的 消費者,一有資料就喚醒消費者
time.
sleep
(time.second)
// 生產完休息一會,給其他協程執行機會}}
//消費者
func
consumer
(in <-
chan
int, idx int
) num :=
<-in // 消費
fmt.
printf
("---- %dth 消費者, 消費資料 %3d,公共區剩餘%d\n"
, idx, num,
len(in)
) cond.l.
unlock()
// 消費結束,解除互斥鎖
cond.
signal()
// 每消費乙個就喚醒生產者
time.
sleep
(time.millisecond *
500)
//消費完 休息一會,給其他協程執行機會}}
func
main()
for i :=
0; i <
5; i++
<-quit // 主協程阻塞 不結束
}
go條件變數的使用和原理
最近寫 時碰到乙個場景,需要使用 map int struct 結構來儲存task,map的key是task的id,隨時可以增減。因為的確除了看書,基本上沒使用過條件變數所以後面過了一天才想到可以用條件變數來實現。記得在某篇部落格上看到的一句話挺不錯,大概是同步語句中,條件變數的特點在於等待。一開始...
Go併發程式設計之美之條件變數
一 前言 go語言類似j a juc包也提供了一些列用於多執行緒之間進行同步的措施,比如低階的同步措施有 鎖 cas 原子變數操作類。相比j a來說go提供了獨特的基於通道的同步措施。本節我們先來看看go中與鎖相關的條件變數 二 條件變數 在j a中條件變數是與具體的鎖想關聯的,在go中也是這樣的。...
Go條件語句
語句 描述if語句 由乙個布林表示式緊跟乙個或多個語句組成.if else if 語句後面可選的else語句,else語句表達時在布林值為false時執行 if 巢狀語句 if elif elif switch 語句 基於不同的條件執行不同的語句 select 語句類似與switch語句,但是sel...