1. 程式人生 > >原 4.5-2 併發技術7:條件變數

原 4.5-2 併發技術7:條件變數

概述

  • sync包下的Cond物件能夠幫我們實現併發中對任意物件的值的監聽
  • 當不滿足條件時,我們進行阻塞等待
  • 而當條件滿足時,我們又能以通知的形式通知等待協程
  • 這有點類似併發中的觀察者模式

案例說明

  • 在下面的例子中,投資者監聽比特幣的市場行情
  • 當行情下跌時,投資者協程阻塞等待等待上漲通知,行情上漲時進行投資
  • 市場協程在比特幣上漲時通知投資者協程
package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	//要監聽的變數
	bitcoinRising := false

	//建立條件變數
	cond := sync.NewCond(&sync.Mutex{})

	/*市場協程*/
	go func() {
		for {

			/*加鎖修改為漲,並通知投資者*/
			cond.L.Lock()
			bitcoinRising = true
			cond.Broadcast()
			cond.L.Unlock()

			//持續漲
			time.Sleep(1 * time.Second)

			/*加鎖修改為跌*/
			cond.L.Lock()
			bitcoinRising = false
			cond.L.Unlock()

			//持續一段時間
			time.Sleep(3 * time.Second)
		}
	}()

	/*投資者協程*/
	for {
		/*
		加鎖閱讀比特幣的變化
		只要比特幣跌,就停止投資,等待漲的訊息(釋放鎖)
		*/
		cond.L.Lock()
		for bitcoinRising==false {
			fmt.Println("停止比特幣投資")

			/*
			阻塞等待訊息
			收到漲的訊息,就繼續向下執行(其它協程通過cond.Signal/Broadcast()傳送漲跌訊息)
			*/
			cond.Wait()//內部將鎖釋放

			//收到了市場變化的訊息後繼續執行
		}

		//走到這裡說明bitcoinRising=true
		fmt.Println("開始投資比特幣...")
		cond.L.Unlock()
	}

}