關於golang的協程並行的控制與示例程序

首先明確一個觀點並行 併發區別: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

相關文章
相關標籤/搜索