首先明確一個觀點並行 併發區別:golang
並行是指程序的運行狀態,要有兩個線程正在執行才能算是Parallelism;併發指程序的邏輯結構,Concurrency則只要有兩個以上線程還在執行過程當中便可。簡單地說,Parallelism要在多核或者多處理器狀況下才能作到,而Concurrency則不須要。golang 利用 go func() 的方式,能夠進行多個函數的並行。bash
咱們寫C 的時候,假如用到多進程,咱們一般都會用信號,管理等來進程進程間的通訊, 那麼golang是怎麼實現這個的呢?? 直接看碼說話吧併發
package main import ( "fmt" "time" ) func main() { timeout := make(chan bool, 1) go func() { fmt.Println("------------ channel 1--------------") t1 := time.Now().UnixNano() fmt.Println(t1) fmt.Println("這個必定會執行") time.Sleep(3 * time.Second) // timeout <- true timeout <- true }() fmt.Println("首先邏輯仍是響應 main 函數") go func() { fmt.Println("------------ channel 2--------------") t2 := time.Now().UnixNano() fmt.Println(t2) fmt.Println("至關於fork一個子進程在進行") }() ch := make(chan int) select { case <-ch: case <-timeout: fmt.Println("------------ 回到main函數 --------------") fmt.Println("task is timeout!") } fmt.Println("main 函數自己的輸出") }
咱們執行代碼看一看結果函數
首先邏輯仍是響應 main 函數 ------------ channel 2-------------- 1471577916141068800 至關於fork一個子進程在進行 ------------ channel 1-------------- 1471577916142068800 這個必定會執行 ------------ 回到main函數 -------------- task is timeout! main 函數自己的輸出
分別從 納秒的時間戳能夠看出, 兩個 go func() 幾乎是同時執行的, 這種是golang並行處理的寫法, goroutine是Go語言運行庫的功能,不是操做系統提供的功能,goroutine不是用線程實現的。, golang一樣提供了一種監視手段去監視每一個並行處理邏輯的返回, select就是這種手段操作系統
按照目前golang的機制,假如調用select的話,循環監控,假如咱們註釋掉 timeout <- true 這句, 看看會有什麼變化, 咱們再執行 go run xx.go 的時候, 會提示 fatal error: all goroutines are asleep - deadlock!, 這是能夠理解爲咱們的 select 監控的多個並行狀態都沒有回調響應,因此程序一直在等待,形成死鎖致使了錯誤。線程
其實golang裏面也能夠用 sync的 waitgroup 進行同步鎖,可是這個跟協程並行彷佛關係不大,有興趣的也能夠了解下code