併發已經成了乙個看起來永遠聊不完的話題,可是有人真的想過併發的實質嗎?當然如果不從哲學意義上討論,僅僅從實用角度考慮的,現行的併發方案確實已經很不錯了,然而事實卻遠遠沒有這麼簡單。
我 在前面很多文章中談到了併發,並且說明了在馮氏機器上其實現的難度,到底為什麼?我們知道作業系統的意義之一就是模擬了硬體,可是作業系統模擬硬體只是為 了提供乙個比真實硬體相對通用的介面,我們把事情想得更加實質一點,作業系統是由程式語言編寫的,其實也是乙個軟體,也就是乙個二進位制的執行流,多程序的 意義並沒有什麼大不了的,我們只需要考慮乙個程序就可以了,多個程序只是通過硬體mmu分離位址空間然後通過os管理的多個二進位制執行流,這多個執行流之 間可以看作是沒有互動的(我們不討論程序間通訊)。然而執行緒共享了位址空間,事情就變得複雜了,傳統作業系統的傳統程序提供的是對真實硬體的模擬但是現代 的執行緒作業系統的程序卻不是對真實硬體的模擬,在現代作業系統中,程序只是乙個資源的容器,而執行緒才是真正的執行流。
我們考慮最簡單的情況,最開始的馮諾依曼機器,單cpu,那麼顯然是單執行流,人類往往很容易形成思維定勢,以後的機器幾乎都是這種單執行流的機器,甚至 強大的c語言本質上就是在模擬單cpu的機器,那麼c++語言,以及基於c語言的linux,甚至windows,unix在本質上都是單cpu執行流的 模擬,也許有人會持有反對觀點,這並不稀奇,因為這正是我馬上就要解釋的。我們看看現在的c語言多麼花哨,用c語言寫成了執行緒庫,那麼利用這個庫的c語言 寫的程式就支援了多執行緒,那麼我們必須面對多執行緒這個本不應該在馮氏家族出生的怪胎。多執行緒起初只是為了合理的利用處理器資源,但是現在多執行緒就意味著並 發,多執行緒的程式在多cpu機器上有了併發的優勢,在《關於兩個世界體系的對話》一文中說道,一切幾乎都是io(讀寫記憶體其實是把記憶體作為外設的io), 以 c語言為代表的傳統的io,實際上是單cpu上單任務工作模式的投影,那麼c語言寫成的多執行緒程式實際上也是單cpu的工作模式,也是io為本的,時鐘校 準機制不允許隨意併發,本來它是不能併發的,如果非要併發,那麼好辦,戴上枷鎖吧,從中可以看出,用c語言搭起來的舞台,舞者必須帶著腳鐐併發跳舞,進一 步,c語言是在馮氏機器的工作縮影,那麼馮氏機器搭起來的舞台,舞者也必須帶著腳鐐跳舞,那麼現在的多核cpu,甚至多cpu是怎麼一回事呢?它們是否突 破了馮氏機器的腳鐐的束縛呢?完全沒有。看看它們的實現吧,隨便了解一點比如mesi的知識就會發現多核cpu包括多cpu機制裡面處處都是腳鐐,同步 啊,各種鎖啊都是,mesi就是乙個例子,只不過其強大的效能和許多花哨的功能掩蓋了沉重的腳鐐。
馮氏機器往上就是c語言,說白了c語言就是馮氏機器的零件,賦值語句就是io指令,語句就是**,變數就是資料…用c語言寫的乙個程式實際上就是一台馮氏 計算機,如果用c語言寫了乙個多執行緒的程式,那麼就相當於這是一台多核或者多cpu的機器,這裡我們假定機器上只跑乙個程序,所謂多個程序只不過是多了一 層作業系統的管理而已。那麼為何馮氏機器不能擺脫枷鎖呢?從歷史上考慮是因為當時沒有考慮到並行,當時是以任務的存在為基準考慮計算機設計的,而不是從任 何的執行上考慮的,當時只是為了使得任務被完成而不考慮怎樣完成或者叫完成的過程,因此,乙個任務就是一次順序的動作,就像我們人做事情一樣,也是乙個順 序的過程,先做什麼再做什麼,統籌學早就已經成了一門學科,我們人類更關心任務能否完成,往往都是只在乎結果而不會享受過程,因此人類序列的大腦當然更容 易想象得出序列的機器,但是這只是原因之一,原因之二就是人類骨子裡天生的權力意志。
作為人類,總希望能統治別人,平等是人類永遠實現不了的夢想,有差距人類才可以進化,強者永遠都會存在,因此這樣的人類發明出來的代替人自身的東西當然不 能是以平等為基礎的,因此誕生了cpu中心論,cpu就是一切的命令發出地,既然有了統治與被統治,有了主和次,那麼並行就很難實現,真正並行的前提就是 大家彼此平等,可能你會說,為何兩個平等的cpu不能去掉枷鎖並行跑呢,當然不能,這裡的不平等並不是說主事者的不平等,而是統治者和被統治者的不平等, 舉個例子就是cpu和外設的不平等,cpu和記憶體的不平等,記憶體或者外設只能聽候cpu的命令將資料從匯流排取下或者將資料放到匯流排上反過來它卻不能直接命 令cpu(中斷的方式?當然不是)。cpu提供了多道程式設計而外設卻沒有,cpu可以執行管理流而外設卻不可以…在這種模式之下,如果cpu要訪問乙個 資源,就要自己先給資源加上鎖,這樣可以阻止和自己平等的另乙個統治者和自己競爭,然後等它用完了資源必須釋放鎖,這時另乙個統治者才可以訪問同乙個資 源,如果資源和cpu平等的話,cpu就不用再加鎖了,因為資源可以自己處理互斥,它自己可以仲裁誰可以訪問誰必須等待,可能你還會說,資源自己仲裁的時 候不還是要鎖嗎?當然是的,但是這已經是更加底層的層次了,在執行這個層次上鎖就消除了,如果用這種平等的觀點對待cpu和io外設的話,作業系統就可以 把io指令也抽象給程序虛擬機器了,因為此時io外設有了cpu的智慧型,io指令再也不是敏感指令了。人類的統治慾望加給計算機就成了以cpu為統治者的馮 氏機器。
我們看一下c語言程式設計,其實不管什麼語言程式設計,大體上大同小異,程式設計的時候其實就好比cpu在執行指令,比如當我寫i++的時候其實就是cpu將變數i遞 增了,當我寫printf的時候實際上就是cpu發出了寫標準輸出的命令,只不過一切都是靜態的罷了。從這個意義上來說cpu完全在執行的時候替代了人的 角色,人統治著這個破敗不堪的世界,cpu同樣統治著那個只有0和1的世界,人類不會讓位統治權,cpu讓位統治權也是很難,因為人類發明了計算機就必須 找乙個統治者來**自己統治0,1世界,畢竟人對於平等沒有任何經驗,而且造物主往往會按照自己的樣子來進行創造。再乙個,我們程式設計實際上也是本著主謂賓 的原則進行的,既然是主謂賓,那麼主和賓的地位本來就是不同的,我們可以實行君主立憲,讓沒有任何執行能力的匯流排來做主,這不失為乙個好的辦法,也就是總 線負責仲裁資源的訪問,限制實體的行為,包括cpu的行為,但是這樣的話我們的程式設計習慣將大大受影響,就好比《關於兩個世界體系的對話》裡面說到的io monad,大家都很不習慣,併發問題在馮氏機器上實際上就是乙個執行順序問題,而執行的順序化是馮氏機器的特徵之一,進一步執行本身是靠時鐘驅動的,只 要時鐘校準了,那麼併發問題就解決了,我們換一種方式解決時鐘校準問題就是用同乙個時鐘,但是用誰的呢?當然是用匯流排的了,因為大家都聯在匯流排上,匯流排相 對於大家來說是平等的,最終的匯流排上還有乙個仲裁器,當然仲裁器內部可能又會有鎖(也可以沒有),不過那已經不是機器架構的範疇了。無鎖並不是不能存在 鎖,而是說不能在執行**的時候特意加鎖,比如cpu不用把加鎖當成同步的手段,而是直接訪問,由被訪問者自己仲裁,不過那時的機器可能就不是cpu在執 行指令了,可能真的就是大家一起來了。
c語言是什麼?c語言就是乙個馮氏機器模擬者,不要想得太難,再重複一遍,它就是馮氏機器的零部件,它內部沒有程序和執行緒的概念的。程序是作業系統的概 念,執行緒是抽象出來的概念,c語言本身並沒有這些東西,之所以有了這麼一些庫,那純粹是為了配合作業系統,比如你可以fork乙個新程序,並且在某個場合 你必須fork出乙個新程序,想深入學習馮氏機器,那學好標準的c語言就夠了,當然如果你很了解馮氏機器,那麼c語言相信你也學得很好。
併發與馮諾依曼體系
1 限制linux伺服器併發連線數 1 系統記憶體大小 記憶體壓力會影響tcp分配socket 2 系統最大檔案控制代碼數量 控制代碼最大數影響network在vfs操作的上限 3 系統ip位址數量 ip位址數,系統ip數越多,建立連線數越多 2 網絡卡 對資料進行封裝和解封,不涉及併發 3 相關結...
通過機器碼程式理解馮諾依曼體系
這篇文章的排版和內容都很糟糕,我會找個時間重寫他。簡介現今所有的商用計算機都是基於馮諾依曼體系的計算機。馮 諾依曼體系結構馮 諾依曼理論的要點是 計算機的數制採用二進位制 計算機應該按照程式順序執行。儲存程式原理,把程式本身當作資料來對待,程式和該程式處理的資料用同樣的方式儲存,二者地位是相等的。通...
馮諾依曼的三大原理
馮.諾依曼的三大原理是 1.計算機由控制器 運算器 儲存器 輸入裝置 輸出裝置五大部分組成。2.程式和資料以二進位制 形式不加區別地存放在儲存器中,存放位置由位址確定。3.控制器根據存放在儲存器中地指令序列 程式 進行工作,並由乙個程式計數器控制指令地執行。控制器具有判斷能力,能根據計算結果選擇不同...