Golang之併發編程二


本文是在上一篇文章的基礎上Golang之併發編程一的基礎上的續篇,若是有興趣的話,你們能夠先看看上一篇的內容,也但願能給出建議,謝謝。php

好了,那接下來繼續說Golang的併發編程吧。html

多核並行化

在說到Golang的並行化時,先看看並行和併發分別是什麼吧。golang

併發:是在單核cpu的基礎上,線程經過時間片或者爭奪和讓出控制權來實現任務的切換,從而實現多個任務的執行。表面上看就好像多個任務在「同時」進行,而其實在某個時間點上,有且僅有一個任務在執行而已。編程

並行:是指多核的CPU能讓同一個進程內的線程,實現真正意義上的同時運行,在理想狀況下是不須要排隊的(實際是線程數量每每多餘cpu核數)。併發

在目前的Go編譯器中,還不可以發揮多核cpu的優點,雖然經過參加goroutine能夠實現多併發,簡化並行代碼的編寫,但這些goroutine都運行在同一個CPU核心上,在一個goroutine獲得時間片執行的時候,其餘goroutine都會處於等待狀態,因此有時候的實際效率可能並無單線程的高。.net

因此在目前的Golang版本中,咱們能夠經過設置環境變量來控制使用多少個CPU核心。線程

runtime.GOMAXPROCS(16)cdn

經過設置環境變量GOMAXPROCS的cpu核數,咱們能夠指定使用多少個cpu核心,另外,咱們能夠經過NumCPU()的方法,來獲取當前計算機的cpu核數。htm

runtime.NumCPU()blog

golang多核

出讓時間片

runtime.Gosched()

當調用這個方法後,該goroutine的會讓出本身的時間片讓其餘goroutine執行。

須要注意的還有一點:當一個goroutine發生阻塞,Go會自動地把與該goroutine處於同一系統線程的其餘goroutines轉移到另外一個系統線程上去,以使這些goroutines不阻塞

同步

雖然使用了channel來做爲通訊手段,但仍是可能避免不了goroutine間的共享數據,因此在golang中,仍是提供了資源鎖的方案

同步鎖

Golang中提供了兩種鎖類型:sync.Mutex 、sync.RWMutex

Mutex:相似Java中的Lock,一個goroutine獲取鎖後其餘goroutine只可以等待,不管讀寫操做。

RWMutex:類型Java中的讀寫鎖,讀鎖佔用時,鎖寫操做,寫鎖佔用時,讀寫都鎖住。

全局惟一性操做

對於全局中只須要運行一次的代碼,如初始化操做,golang提供了一個Once類型來保證惟一性操做

var once sync.Once

once.Do(方法名)

調用once.Do時,其餘goroutine會被阻塞,知道全局惟一的once.Do()調用結束後才繼續

示例:

var a string

var once sync.Once

func setup() {

a = "hello world"

}

func doprint() {

once.Do(setup)

print(a)

}

額外閱讀:golang線程同步WaitGroup

認識golang併發

簡書:http://www.jianshu.com/p/76c8356a4338

相關文章
相關標籤/搜索