go協程


一。並發&並行

一個應用程序  ---> 一個進程 ---> 運行在自己內存地址空間里的獨立執行體 ---> 同一個內存地址空間的一起工作的多個線程

 

一個並發程序 ---> 多個線程來執行任務 ---> 某個時間點同時運行在多核或者多處理器 ---> 並發&並行

                                                       ---> 某個時間點同時運行在單個處理器     --\---> 並發&不並行

 

並行是一種通過使用多處理器以提高速度的能力。所以並發程序可以是並行的,也可以不是。

 

公認的,使用多線程的應用難以做到准確,最主要的問題是內存中的數據共享,它們會被多線程以無法預知的方式進行操作,導致一些無法重現或者隨機的結果(稱作 競態

並發方式:

1.確定性的(明確定義排序)

2.非確定性的(加鎖/互斥從而未定義排序)---> 競態

不要使用全局變量或者共享內存,它們會給你的代碼在並發運算的時候帶來危險。

 

解決之道:

1.同步不同的線程,對數據加鎖,這樣同時就只有一個線程可以變更數據

2.有個被稱作 Communicating Sequential Processes(順序通信處理)(CSP, C. Hoare 發明的)

3.還有一個叫做 message passing-model(消息傳遞)(已經運用在了其他語言中,比如 Erlang)

 

二。go的協程

在 Go 中,應用程序並發處理的部分被稱作 goroutines(協程)

協程 ---> 工作在相同的地址空間 ---> 共享內存的方式一定是同步的;這個可以使用 sync 包來實現(不推薦)

       ---> 使用 channels 來同步協程

特點:

1.使用少量的內存和資源:使用 4K 的棧內存就可以在堆中創建它們

2.對棧進行了分割,從而動態的增加(或縮減)內存的使用;棧的管理是自動的,但不是由垃圾回收器管理的,而是在協程退出后自動釋放

3.協程可以運行在多個操作系統線程之間,也可以運行在線程之內

4.使用少量的操作系統線程就能擁有任意多個提供服務的協程,而且 Go 運行時可以聰明的意識到哪些協程被阻塞了,暫時擱置它們並處理其他協程

5.存在兩種並發方式:確定性的(明確定義排序)和非確定性的(加鎖/互斥從而未定義排序)。Go 的協程和通道理所當然的支持確定性的並發方式(例如通道具有一個 sender 和一個 receiver)

 

實現形式:

關鍵字 go 調用 ---> 一個函數或者方法 ---> 在當前的計算過程中開始一個同時進行的函數 ---> 在相同的地址空間中並且分配了獨立的棧(棧分割)

協程的棧會根據需要進行伸縮,不出現棧溢出;開發者不需要關心棧的大小。當協程結束的時候,它會靜默退出:用來啟動這個協程的函數不會得到任何的返回值

 

三。go協程並行:

Go 默認沒有並行指令,只有一個獨立的核心或處理器被專門用於 Go 程序,不論它啟動了多少個協程;所以這些協程是並發運行的,但他們不是並行運行的:同一時間只有一個協程會處在運行狀態

在 gc 編譯器下(6g 或者 8g)你必須設置 GOMAXPROCS 為一個大於默認值 1 的數值來允許運行時支持使用多於 1 個的操作系統線程,所有的協程都會共享同一個線程除非將 GOMAXPROCS 設置為一個大於 1 的數。當 GOMAXPROCS 大於 1 時,會有一個線程池管理許多的線程。通過 gccgo 編譯器 GOMAXPROCS 有效的與運行中的協程數量相等。假設 n 是機器上處理器或者核心的數量。如果你設置環境變量 GOMAXPROCS>=n,或者執行 runtime.GOMAXPROCS(n),接下來協程會被分割(分散)到 n 個處理器上。更多的處理器並不意味着性能的線性提升。有這樣一個經驗法則,對於 n 個核心的情況設置 GOMAXPROCS 為 n-1 以獲得最佳性能,也同樣需要遵守這條規則:協程的數量 > 1 + GOMAXPROCS > 1。

所以如果在某一時間只有一個協程在執行,不要設置 GOMAXPROCS!

還有一些通過實驗觀察到的現象:在一台 1 顆 CPU 的筆記本電腦上,增加 GOMAXPROCS 到 9 會帶來性能提升。在一台 32 核的機器上,設置 GOMAXPROCS=8 會達到最好的性能,在測試環境中,更高的數值無法提升性能。如果設置一個很大的 GOMAXPROCS 只會帶來輕微的性能下降;設置 GOMAXPROCS=100,使用 top 命令和 H 選項查看到只有 7 個活動的線程。

增加 GOMAXPROCS 的數值對程序進行並發計算是有好處的;

總結:GOMAXPROCS 等同於(並發的)線程數量,在一台核心數多於1個的機器上,會盡可能有等同於核心數的線程在並行運行。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM