前言:要了解協程和管道首先得了解以下四個概念
進程和線程簡單說明
1.進程就是程序在操作系統中的一次執行過程,是系統進行資源分配和調度的基本單位
2.線程是進程的一個執行實例,是程序執行的最小單元,它是比進程更小的獨立運行的基本單位
3.一個進程可以創建銷燬多個線程,同一個進程的多個線程可以併發執行
4.一個程序至少有一個進程,一個進程至少有一個線程
個人理解:把計算機比作一家公司,程序就是這家公司的部門,進程就是公司安排的某個工作內容的完成過程,線程就是部門裏處理這個工作內容的人去完成的實例,公司下發工作內容就相當於給部門下發任務,由公司(這裏公司就是隻CPU,後面會跟併發和並行有關聯)來調動相應的人數去處理這個或者這些任務,如有錯誤請指出,謝謝。
併發和並行
1.多線程程序在單核上運行,就是併發
2.多線程程序在多核上運行,就是並行
個人理解:沿用上一個例子,併發就是有多個任務安排,但是現在部門內部只有一個人,這個人就得同時處理所有工作內容,感覺上是所有的任務都在同時處理,但實際上在一個時間點上,這個人只能處理一個問題,只是在不停地切換不同的任務處理,而非處理完成一個任務後再切換到下一個任務。並行就是部門內部有多個人,可以同時處理多個任務
GO的協程和主線程
1.GO主線程(有程序員直接稱爲線程/也可以理解成進程),一個GO線程上,可以起多個協程,可以這樣理解,協程是輕量級的線程(編譯器做優化)。
2.GO協程的特點
- 有獨立的棧空間
- 有共享程序堆空間
- 調度由用戶控制
- 協程是輕量級的線程
goroutine 快速入門小結
1.主線程是一個物理線程嗎,直接作用在cpu上的,是重量級的,非常消耗cpu資源。
2.協程從主線程開啓的,是輕量級的線程,是邏輯態的。對資源消耗相對小。
3.Golang的協程機制是重要的特點,可以輕鬆的開啓上萬個協程。其他編程語言的併發機制是一般基於線程的,開啓過多的線程,資源消耗大,這就突顯了Golang在併發上的優勢
goroutine的調度模型(MPG模式)
基本介紹
M:操作系統的主線程(是物理線程)
P:協程執行需要的上下文
G:協程
簡單來說,就是一個協程阻塞了,會把後續操作自動放到其餘空閒的協程中執行,等到阻塞協程完成後,會把剩餘的任務又使用該線程繼續執行。這樣來回切換可以保證阻塞的協程不會影響效率。達成併發/並行的效果
內容較多,需詳細瞭解請自行搜索查詢。
Channel(管道)
在協程中進行相互通信時(都要使用同一個全局變量)會產生資源競爭(同時對某一個全局變量進行讀寫)的問題。
channel用於解決不同的goroutine之間通信的問題,也可以使用加互斥鎖的方式來達成這個目的。但互斥鎖沒這玩意兒好。
基本介紹
1.channel本質就是一個數據結構-隊列
2.數據是先進先出,與棧是相反的,棧是先進後出
3.線程安全,多個goroutine訪問時,不需要加鎖,本身就是線程安全的
4.channel是有類型的,一個string的channel只能存放string類型的數據
定義/聲明
var 變量名 chan 數據類型
舉例:
var intChan chan int
var stringChan chan string
var structChan chan Struct (結構體)
var mapChan chan map[string]int (map)
channel是一個引用類型,必須初始化才能寫入數據,即使用make進行初始化,第二個參數爲channel的長度
int類型的管道只能存放int類型的數據
給管道寫入數據,拿上面的intChan舉例
讀取管道中的數據
channel的遍歷
channel支持for-range的方式進行遍歷,但注意兩個細節
1.在遍歷時,如果chanel沒有關閉,則會出現deadlock的錯誤
2.在遍歷時,如果channel已經關閉,則會正常遍歷數據,遍歷完後,就會退出遍歷
channel和goroutine使用的注意事項
1.channel總只能存放指定的數據類型
2.channel的數據放滿後就不能再放入
3.如果從channel取出數據後,可以繼續放入
4.在沒有使用協程的情況下,如果channel的數據取完了,再取就會報dead lock,channel在取值時,實際上會返回兩個值,x,ok:=<-chan,第二個值爲ok,在成功取出,爲false則失敗
5.使用內置函數close可以關閉channel,當channel關閉後,就不能再向channel寫數據了,但是仍然可以從該channel讀取數據。
6.在默認情況下,channel管道是雙向的,即可度又可寫
var chan2 chan <- int //只可寫入的int型管道
var chan2 <-chan int //只可讀取的int型管道
7.使用select可以解決從channel管道中讀取數據的阻塞問題
8.groutine中使用recover,解決協程中出現的panic,防止程序出現崩潰