【前言】go語言的併發機制以及它所使用的CSP併發模型html
CSP模型是上個世紀七十年代提出的,用於描述兩個獨立的併發實體經過共享的通信 channel(管道)進行通訊的併發模型。 CSP中channel是第一類對象,它不關注發送消息的實體,而關注與發送消息時使用的channel。java
Golang 就是借用CSP模型的一些概念爲之實現併發進行理論支持,其實從實際上出發,go語言並無,徹底實現了CSP模型的全部理論,僅僅是借用了 process和channel這兩個概念。process是在go語言上的表現就是 goroutine 是實際併發執行的實體,每一個實體之間是經過channel通信來實現數據共享。 golang
Golang中使用 CSP中 channel 這個概念。channel 是被單首創建而且能夠在進程之間傳遞,它的通訊模式相似於 boss-worker 模式的,一個實體經過將消息發送到channel 中,而後又監聽這個 channel 的實體處理,兩個實體之間是匿名的,這個就實現實體中間的解耦,其中 channel 是同步的一個消息被髮送到 channel 中,最終是必定要被另外的實體消費掉的,在實現原理上實際上是一個阻塞的消息隊列。算法
Goroutine 是實際併發執行的實體,它底層是使用協程(coroutine)實現併發,coroutine是一種運行在用戶態的用戶線程(協程),相似於 greenthread,go底層選擇使用coroutine的出發點是由於,它具備如下特色:編程
能夠看到第二條 用戶空間線程的調度不是由操做系統來完成的,像在java 1.3中使用的greenthread的是由JVM統一調度的(後java已經改成內核線程),還有在ruby中的fiber(半協程) 是須要在從新中本身進行調度的,而goroutine是在golang層面提供了調度器,而且對網絡IO庫進行了封裝,屏蔽了複雜的細節,對外提供統一的語法關鍵字支持,簡化了併發程序編寫的成本。ruby
goroutine運行在相同的地址空間,所以訪問共享內存必須作好同步。goroutine經過通道(channel)來通訊,而不是共享內存。使用channel用於多個goroutine通訊,內部實現同步。channel底層是一個相似map的數據結構的引用。即,引用傳參。網絡
golang使用goroutine作爲最小的執行單位,可是這個執行單位仍是在用戶空間,實際上最後被處理器執行的仍是內核中的線程,用戶線程和內核線程的調度方法有:數據結構
N:1 多個用戶線程對應一個內核線程併發
1:1 一個用戶線程對應一個內核線程oracle
M:N 用戶線程和內核線程是多對多的對應關係
golang 經過爲goroutine提供語言層面的調度器,來實現了高效率的M:N線程對應關係
圖中
Golang爲了調度的公平性,在調度器加入了steal working 算法 ,在一個P本身的執行隊列,處理完以後,它會先到全局的執行隊列中偷G進行處理,若是沒有的話,再會到其餘P的執行隊列中搶G來進行處理。
可參考:http://www.javashuo.com/article/p-udofcdfr-bu.html
Golang實現了 CSP 併發模型作爲併發基礎,底層使用goroutine作爲併發實體,goroutine很是輕量級能夠建立幾十萬個實體。實體間經過 channel(底層引用數據) 繼續匿名消息傳遞使之解耦,在語言層面實現了自動調度,這樣屏蔽了不少內部細節,對外提供簡單的語法關鍵字,大大簡化了併發編程的思惟轉換和管理線程的複雜性。