多进程单线程模型与单进程多线程模型之争
似乎有人不知道nodejs是支持多核的?v0.10 Cluster可以搭建nodejs多核服務(wù)。v0.12重寫了Cluster,據(jù)說(shuō)提升了非常大的性能。
服務(wù)器,事件
多進(jìn)程單線程模型典型代表:nginx
單進(jìn)程多線程模型典型代表:memcached
另外redis, mongodb也可以說(shuō)是走的“多進(jìn)程單線程模”模型(集群),只不過(guò)作為數(shù)據(jù)庫(kù)服務(wù)器,需要進(jìn)行寫保護(hù),只提供了讀同步。
原因很簡(jiǎn)單,因?yàn)榉?wù)器的發(fā)展大部分都是歸功于Linux Unix,而不是Windows。
Linux內(nèi)核提供的epoll為開發(fā)服務(wù)器提供了很大的便利,libevent和libev都是對(duì)epoll的封裝,nginx自己實(shí)現(xiàn)了對(duì)epoll的封裝。
libevent和libev都是知名的Linux系統(tǒng)C事件驅(qū)動(dòng)編程框架。
我沒(méi)說(shuō)錯(cuò)的話,nodejs是建立在libev基礎(chǔ)上。
memcached也依賴libevent。
所以,nginx在Windows上不像Linux快是有很大原因的。
模型,模型,多進(jìn)程單線程 單進(jìn)程多線程
-
多進(jìn)程單線程
master進(jìn)程管理worker進(jìn)程:
- 接收來(lái)自外界的信號(hào)
- 向各worker進(jìn)程發(fā)送信號(hào)
- 監(jiān)控woker進(jìn)程的運(yùn)行狀態(tài)
- 當(dāng)woker進(jìn)程退出后(異常情況下),會(huì)自動(dòng)重新啟動(dòng)新的woker進(jìn)程
友情提示:nodejs屬于這一種好不好,不是只能單核
單進(jìn)程多線程
-
單進(jìn)程多線程
主線程負(fù)責(zé)監(jiān)聽客戶端的連接請(qǐng)求,workers線程負(fù)責(zé)處理已經(jīng)建立好的連接的讀寫等事件
單進(jìn)程多線程
單進(jìn)程多線程肯定比多進(jìn)程單線程快一些
多進(jìn)程單線程與單進(jìn)程多線程的目的都是想盡可能的利用CPU,減少CPU的空閑時(shí)間,特別是多核環(huán)境。
他們?cè)趯?shí)際運(yùn)行中,所利用的CPU工作數(shù)應(yīng)該都是相同的。也就是說(shuō),你有4核,在某個(gè)時(shí)刻要么是CPU同時(shí)在4個(gè)進(jìn)程做任務(wù)(多進(jìn)程單線程),要么是CPU同時(shí)在4個(gè)線程上做任務(wù)(單進(jìn)程多線程)。
不過(guò),單進(jìn)程多線程肯定比多進(jìn)程單線程快一些。
這是因?yàn)?#xff0c;多進(jìn)程單線程的CPU切換,是從一個(gè)進(jìn)程到另一個(gè)進(jìn)程,而單進(jìn)程多線程的CPU切換則只在一個(gè)進(jìn)程內(nèi),每個(gè)進(jìn)程|線程都有自己的上下文堆棧保存,進(jìn)程間的切換消耗更大一些。
這就好比是,多進(jìn)程單線程是在4個(gè)函數(shù)中切換,各自擁有自己的變量;單進(jìn)程多線程在1個(gè)函數(shù)中的4個(gè)子函數(shù)切換,擁有相同的全局變量。
但是,沒(méi)有你想象的“快幾倍”。
副作用,副作用,單進(jìn)程多線程肯定有其不利的一面
我一直提過(guò)副作用。
如果你仔細(xì)看多進(jìn)程單線程的圖,就應(yīng)該明白,這種模型提供了一種保護(hù)機(jī)制。
當(dāng)其中一個(gè)進(jìn)程內(nèi)部讀取錯(cuò)誤,master可以讓ta重啟。這使得你的服務(wù)器在表面上并沒(méi)有感到“曾經(jīng)崩潰”。
對(duì)于master,完全不涉及服務(wù)器的業(yè)務(wù),使得ta能被安全隔離。
再來(lái)看單進(jìn)程多線程。
問(wèn)題很明顯,只有一個(gè)進(jìn)程,一旦其中出現(xiàn)一個(gè)錯(cuò)誤,整個(gè)進(jìn)程都有可能掛掉。你當(dāng)然可以為ta編寫一個(gè)“守護(hù)程序”來(lái)重啟,但是重啟期間,你的服務(wù)器是真的“掛掉了”。
另外,編寫單進(jìn)程多線程這樣的服務(wù)器,在代碼上非常容易出錯(cuò),而且難以控制代碼的穩(wěn)定性,有很多你難以琢磨的bug在等著你,因?yàn)橛刑嗟逆i,太多的全局變量需要處理,這也是函數(shù)式“純函數(shù)”所反對(duì)的。
nodejs不能CPU密集處理?
你覺(jué)得ruby,python,php就能密集處理?
有人說(shuō):java, c#。
拜托,如果你真的想要密集處理,請(qǐng)使用C C++。(我個(gè)人只會(huì)用C)你見過(guò)哪個(gè)數(shù)據(jù)庫(kù)服務(wù)器是java c#寫的?
而現(xiàn)在,我覺(jué)得Rust lang是一個(gè)好的方向:
- 面向操作系統(tǒng)編程
- 從語(yǔ)言層面上提供并發(fā)
- 自詡C++的替代者
- 將會(huì)重寫firefox
- Mozilla開發(fā)
- Javascript的作者Brendan Eich是編寫者之一
- 類似javascript的語(yǔ)法和編寫體驗(yàn)
而且我已經(jīng)開始憧憬未來(lái)使用nodejs + Rust開發(fā)服務(wù)器體驗(yàn)的場(chǎng)景。
總結(jié)
以上是生活随笔為你收集整理的多进程单线程模型与单进程多线程模型之争的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 爱创课堂每日一题第四十天- 说说你对语义
- 下一篇: 通过添加HTTP Header实现上下文