天天看點

[Go基礎]--Go是怎麼來的?

1、pthread是包在OS線程外的。

2、light-weighted thread需要用到使用者态線程。

3、微軟的fiber是使用者态的,但是因為是windows世界的,不怎麼招人待見。

4、在多核上做使用者态線程是一件非常非常惡心的事情,GO最主要的貢獻其實 就是把這件事做成了。

主要的惡心之處就是怎麼處理job stealing:一個 操統線程上面的任務都跑完了,就需要去别的操統線程那兒把活弄過來。 這就涉及到各種同步,各種locking。Locking多了,性能就下來了。

這種事情以前應該不少公司内部都有人做過,能做這個的人一般也都 屌得不得了。其實稍微對比一下就能知道multi-core有多難做: node.js不支援multi-core,python折騰這麼多年也還是個殘疾。

如果你想更多地了解一下,可以從man makecontext 看起。每個使用者态線程其實是一個context。然後底下每個操統線程負責 管一堆context。context切換主要靠cooperative scheduling,而不是操統 用的preemptive scheduling。也就是說一個context運作到某一步自己主動 把執行權讓出來。Unix世界的一般沒見過cooperative scheduling. Windows 3.x是cooperative scheduling,是以線程跑一會就得調用yield 讓出執行權。因為不可能要求程式員寫幾行程式就插入一個yield,是以 其實Windows很多UI和I/O的API都内嵌了yield。那些差的程式員不知道 這回事,有時候進入一個純計算的循環沒有在中間插入yield,就會導緻 系統挂起。

Unix世界從一開始就是pre-emptive的,操統API沒有内嵌yield 這回事。手寫程式隔幾行插入yield也不可行。這就是unix世界的C/C++做 使用者态線程幾乎不肯能的原因。這也是為啥rob pike非要搞一個新的語言的 原因:在操統API外包一層,并且嵌入yield(還有就是GC)。GO在語言層面 上其實沒有任何創新,甚至比好多現有的語言都要低級。如果從出發點來 看,GO的目的其實已經達到了。相比而言,Windows有在API 裡面做yield的傳統,這也是為什麼這麼容易搞出來fiber的原因。

繼續閱讀