多进程 VS 多线程
在Linux下編程多用多進程編程少用多線程編程。
???????? IBM有個家伙做了個測試,發(fā)現(xiàn)切換線程context的時候,windows比linux快一倍多。進出最快的鎖(windows2k的 critical section和linux的pthread_mutex),windows比linux的要快五倍左右。當然這并不是說linux不好,而且在經(jīng)過實際編程之后,綜合來看我覺得linux更適合做high performance server,不過在多線程這個具體的領域內(nèi),linux還是稍遜windows一點。這應該是情有可原的,畢竟unix家族都是從多進程過來的,而 windows從頭就是多線程的。
如果是UNIX/linux環(huán)境,采用多線程沒必要。
多線程比多進程性能高?誤導!
應該說,多線程比多進程成本低,但性能更低。
在UNIX環(huán)境,多進程調(diào)度開銷比多線程調(diào)度開銷,沒有顯著區(qū)別,就是說,UNIX進程調(diào)度效率是很高的。內(nèi)存消耗方面,二者只差全局數(shù)據(jù)區(qū),現(xiàn)在內(nèi)存都很便宜,服務器內(nèi)存動輒若干G,根本不是問題。
多進程是立體交通系統(tǒng),雖然造價高,上坡下坡多耗點油,但是不堵車。
多線程是平面交通系統(tǒng),造價低,但紅綠燈太多,老堵車。
我們現(xiàn)在都開跑車,油(主頻)有的是,不怕上坡下坡,就怕堵車。
高性能交易服務器中間件,如TUXEDO,都是主張多進程的。實際測試表明,TUXEDO性能和并發(fā)效率是非常高的。TUXEDO是貝爾實驗室的,與UNIX同宗,應該是對UNIX理解最為深刻的,他們的意見應該具有很大的參考意義。
====================================================================================================
多線程的優(yōu)點:
無需跨進程邊界;?
程序邏輯和控制方式簡單;?
所有線程可以直接共享內(nèi)存和變量等;?
線程方式消耗的總資源比進程方式好;?
多線程缺點:
每個線程與主程序共用地址空間,受限于2GB地址空間;?
線程之間的同步和加鎖控制比較麻煩;?
一個線程的崩潰可能影響到整個程序的穩(wěn)定性;?
到達一定的線程數(shù)程度后,即使再增加CPU也無法提高性能,例如Windows Server 2003,大約是1500個左右的線程數(shù)就快到極限了(線程堆棧設定為1M),如果設定線程堆棧為2M,還達不到1500個線程總數(shù);?
線程能夠提高的總性能有限,而且線程多了之后,線程本身的調(diào)度也是一個麻煩事兒,需要消耗較多的CPU?
多進程優(yōu)點:
每個進程互相獨立,不影響主程序的穩(wěn)定性,子進程崩潰沒關系;
通過增加CPU,就可以容易擴充性能;
可以盡量減少線程加鎖/解鎖的影響,極大提高性能,就算是線程運行的模塊算法效率低也沒關系;
每個子進程都有2GB地址空間和相關資源,總體能夠達到的性能上限非常大
多線程缺點:
邏輯控制復雜,需要和主程序交互;?
需要跨進程邊界,如果有大數(shù)據(jù)量傳送,就不太好,適合小數(shù)據(jù)量傳送、密集運算?
多進程調(diào)度開銷比較大;?
最好是多進程和多線程結合,即根據(jù)實際的需要,每個CPU開啟一個子進程,這個子進程開啟多線程可以為若干同類型的數(shù)據(jù)進行處理。當然你也可以利用多線程+多CPU+輪詢方式來解決問題……
方法和手段是多樣的,關鍵是自己看起來實現(xiàn)方便有能夠滿足要求,代價也合適。
---------------------------------------------------------
進程的優(yōu)點:
1)順序程序的特點:具有封閉性和可再現(xiàn)性;
2)程序的并發(fā)執(zhí)行和資源共享。多道程序設計出現(xiàn)后,實現(xiàn)了程序的并發(fā)執(zhí)行和資源共享,提高了系統(tǒng)的效率和系統(tǒng)的資源利用率。
進程的缺點:
操作系統(tǒng)調(diào)度切換多個線程要比切換調(diào)度進程在速度上快的多。而且進程間內(nèi)存無法共享,通訊也比較麻煩。
線程之間由于共享進程內(nèi)存空間,所以交換數(shù)據(jù)非常方便;在創(chuàng)建或撤消進程時,由于系統(tǒng)都要為之分配和回收資源,導致系統(tǒng)的開銷明顯大于創(chuàng)建或撤消線程時的開銷。
? ?
線程的優(yōu)點:
1)它是一種非常"節(jié)儉"的多任務操作方式。在Linux系統(tǒng)下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的數(shù)據(jù)表來維護它的代碼段、堆棧段和數(shù)據(jù)段,這是一種"昂貴"的多任務工作方式。而運行于一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數(shù)據(jù),啟動一個線程所花費的空間遠遠小于啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小于進程間切換所需要的時間。當然,在具體的系統(tǒng)上,這個數(shù)據(jù)可能會有較大的區(qū)別;
2)線程間方便的通信機制,由于同一進程下的線程之間共享數(shù)據(jù)空間,所以一個線程的數(shù)據(jù)可以直接為其它線程所用,這不僅快捷,而且方便;
3)使多CPU系統(tǒng)更加有效。操作系統(tǒng)會保證當線程數(shù)不大于CPU數(shù)目時,不同的線程運行于不同的CPU上;
4)改善程序結構。一個既長又復雜的進程可以考慮分為多個線程,成為幾個獨立或半獨立的運行部分,這樣的程序會利于理解和修改。
線程的缺點:
1.調(diào)度時, 要保存線程狀態(tài),頻繁調(diào)度, 需要占用大量的機時;
2.程序設計上容易出錯(線程同步問題)。
有人為二者對比專門做過實驗,特此轉(zhuǎn)載過來
在Unix上編程采用多線程還是多進程的爭執(zhí)由來已久,這種爭執(zhí)最常見到在C/S通訊中服務端并發(fā)技術 的選型上,比如WEB服務器技術中,Apache是采用多進程的(perfork模式,每客戶連接對應一個進程,每進程中只存在唯一一個執(zhí)行線程),?Java的Web容器Tomcat、Websphere等都是多線程的(每客戶連接對應一個線程,所有線程都在一個進程中)。
從Unix發(fā)展歷史看,伴隨著Unix的誕生進程就出現(xiàn)了,而線程很晚才被系統(tǒng)支持,例如Linux直到內(nèi)核2.6,才支持符合Posix規(guī)范的NPTL線程庫。進程和線程的特點,也就是各自的優(yōu)缺點如下:
進程優(yōu)點:編程、調(diào)試簡單,可靠性較高。
進程缺點:創(chuàng)建、銷毀、切換速度慢,內(nèi)存、資源占用大。
線程優(yōu)點:創(chuàng)建、銷毀、切換速度快,內(nèi)存、資源占用小。
線程缺點:編程、調(diào)試復雜,可靠性較差。
上面的對比可以歸結為一句話:“線程快而進程可靠性高”。線程有個別名叫“輕量級進程”,在有的書籍資料上介紹線程可以十倍、百倍的效率快于進程; 而進程之間不共享數(shù)據(jù),沒有鎖問題,結構簡單,一個進程崩潰不像線程那樣影響全局,因此比較可靠。我相信這個觀點可以被大部分人所接受,因為和我們所接受 的知識概念是相符的。
在寫這篇文章前,我也屬于這“大部分人”,這兩年在用C語言編寫的幾個C/S通訊程序中,因時間緊總是采用多進程并發(fā)技術,而且是比較簡單的現(xiàn)場為 每客戶fork()一個進程,當時總是擔心并發(fā)量增大時負荷能否承受,盤算著等時間充裕了將它改為多線程形式,或者改為預先創(chuàng)建進程的形式,直到最近在網(wǎng) 上看到了一篇論文《Linux系統(tǒng)下多線程與多進程性能分析》作者“周麗 焦程波 蘭巨龍”,才認真思考這個問題,我自己也做了實驗,結論和論文作者的相似,但對大部分人可以說是顛覆性的。
下面是得出結論的實驗步驟和過程,結論究竟是怎樣的? 感興趣就一起看看吧。
實驗代碼使用周麗論文中的代碼樣例,我做了少量修改,值得注意的是這樣的區(qū)別:
論文實驗和我的實驗時間不同,論文所處的年代linux內(nèi)核是2.4,我的實驗linux內(nèi)核是2.6,2.6使用的線程庫是NPTL,2.4使用的是老的Linux線程庫(用進程模擬線程的那個LinuxThread)。
文實驗和我用的機器不同,論文描述了使用的環(huán)境:單 cpu 機器基本配置為:celeron 2.0 GZ, 256M, Linux 9.2,內(nèi)核 2.4.8。我的環(huán)境是我的工作本本:單cpu單核celeron(R) M 1.5 GZ,1.5G內(nèi)存,ubuntu10.04 desktop,內(nèi)核2.6.32。
進程實驗代碼(fork.c):
[cpp]?view plaincopy
[cpp]?view plaincopy
兩段程序做的事情是一樣的,都是創(chuàng)建“若干”個進程/線程,每個創(chuàng)建出的進程/線程打印“若干”條“hello linux”字符串到控制臺和日志文件,兩個“若干”由兩個宏 P_NUMBER和COUNT分別定義,程序編譯指令如下:
[cpp]?view plaincopy
實驗通過time指令執(zhí)行兩個程序,抄錄time輸出的掛鐘時間(real時間):
[cpp]?view plaincopy
每批次的實驗通過改動宏 P_NUMBER和COUNT來調(diào)整進程/線程數(shù)量和打印次數(shù),每批次測試五輪,得到的結果如下:
一、重復周麗論文實驗步驟
| 多進程 | 0m1.277s | 0m1.175s | 0m1.227s | 0m1.245s | 0m1.228s | 0m1.230s |
| 多線程 | 0m1.150s | 0m1.192s | 0m1.095s | 0m1.128s | 0m1.177s | 0m1.148s |
進程線程數(shù):255 / 打印次數(shù):100
| 多進程 | 0m6.341s | 0m6.121s | 0m5.966s | 0m6.005s | 0m6.143s | 0m6.115s |
| 多線程 | 0m6.082s | 0m6.144s | 0m6.026s | 0m5.979s | 0m6.012s | 0m6.048s |
進程線程數(shù):255 / 打印次數(shù):500
| 多進程 | 0m12.155s | 0m12.057s | 0m12.433s | 0m12.327s | 0m11.986s | 0m12.184s |
| 多線程 | 0m12.241s | 0m11.956s | 0m11.829s | 0m12.103s | 0m11.928s | 0m12.011s |
進程線程數(shù):255 / 打印次數(shù):1000
| 多進程 | 1m2.182s | 1m2.635s | 1m2.683s | 1m2.751s | 1m2.694s | 1m2.589s |
| 多線程 | 1m2.622s | 1m2.384s | 1m2.442s | 1m2.458s | 1m3.263s | 1m2.614s |
進程線程數(shù):255 / 打印次數(shù):5000
本輪實驗是為了和周麗論文作對比,因此將進程/線程數(shù)量限制在255個,論文也是測試了255個進程/線程分別進行10 次,50 次,100 次,200 次……900 次打印的用時,論文得出的結果是:任務量較大時,多進程比多線程效率高;而完成的任務量較小時,多線程比多進程要快,重復打印 600 次時,多進程與多線程所耗費的時間相同。
雖然我的實驗直到5000打印次數(shù)時,多進程才開始領先,但考慮到使用的是NPTL線程庫的緣故,從而可以證實了論文的觀點。從我的實驗數(shù)據(jù)看,多線程和多進程兩組數(shù)據(jù)非常接近,考慮到數(shù)據(jù)的提取具有瞬間性,因此可以認為他們的速度是相同的。
當前的網(wǎng)絡環(huán)境中,我們更看中高并發(fā)、高負荷下的性能,縱觀前面的實驗步驟,最長的實驗周期不過1分鐘多一點,因此下面的實驗將向兩個方向延伸,第一,增加并發(fā)數(shù)量,第二,增加每進程/線程的工作強度。
二、增加并發(fā)數(shù)量的實驗
下面的實驗打印次數(shù)不變,而進程/線程數(shù)量逐漸增加。在實驗過程中多線程程序在后三組(線程數(shù)500,800,1000)的測試中都出現(xiàn)了“段錯誤”,出現(xiàn)錯誤的原因和線程棧的大小有關。
實驗中的計算機CPU是32位的賽揚,尋址最大范圍是4GB(2的32次方),Linux是按照3GB/1GB的方式來分配內(nèi)存,其中1GB屬于所 有進程共享的內(nèi)核空間,3GB屬于用戶空間(進程虛擬內(nèi)存空間),對于進程而言只有一個棧,這個棧可以用盡這3GB空間(計算時需要排除程序文本、數(shù)據(jù)、 共享庫等占用的空間),所以它的大小通常不是問題。但對線程而言每個線程有一個線程棧,這3GB空間會被所有線程棧攤分,線程數(shù)量太多時,線程棧累計的大 小將超過進程虛擬內(nèi)存空間大小,這就是實驗中出現(xiàn)的“段錯誤”的原因。
Linux2.6的默認線程棧大小是8M,可以通過 ulimit -s 命令查看或修改,我們可以計算出線程數(shù)的最大上線: (1024*1024*1024*3) / (1024*1024*8) = 384,實際數(shù)字應該略小與384,因為還要計算程序文本、數(shù)據(jù)、共享庫等占用的空間。在當今的稍顯繁忙的WEB服務器上,突破384的并發(fā)訪問并不是稀 罕的事情,要繼續(xù)下面的實驗需要將默認線程棧的大小減小,但這樣做有一定的風險,比如線程中的函數(shù)分配了大量的自動變量或者函數(shù)涉及很深的棧幀(典型的是 遞歸調(diào)用),線程棧就可能不夠用了。可以配合使用POSIX.1規(guī)定的兩個線程屬性guardsize和stackaddr來解決線程棧溢出問題, guardsize控制著線程棧末尾之后的一篇內(nèi)存區(qū)域,一旦線程棧在使用中溢出并到達了這片內(nèi)存,程序可以捕獲系統(tǒng)內(nèi)核發(fā)出的告警信號,然后使用 malloc獲取另外的內(nèi)存,并通過stackaddr改變線程棧的位置,以獲得額外的棧空間,這個動態(tài)擴展棧空間辦法需要手工編程,而且非常麻煩。
有兩種方法可以改變線程棧的大小,使用 ulimit -s 命令改變系統(tǒng)默認線程棧的大小,或者在代碼中創(chuàng)建線程時通過pthread_attr_setstacksize函數(shù)改變棧尺寸,在實驗中使用的是第一 種,在程序運行前先執(zhí)行ulimit指令將默認線程棧大小改為1M:
[cpp]?view plaincopy
| 多進程 | 0m4.958s | 0m5.032s | 0m5.181s | 0m4.951s | 0m5.032s | 0m5.031s |
| 多線程 | 0m4.994s | 0m5.040s | 0m5.071s | 0m5.113s | 0m5.079s | 0m5.059s |
進程線程數(shù):100 / 打印次數(shù):1000
| 多進程 | 0m12.155s | 0m12.057s | 0m12.433s | 0m12.327s | 0m11.986s | 0m12.184s |
| 多線程 | 0m12.241s | 0m11.956s | 0m11.829s | 0m12.103s | 0m11.928s | 0m12.011s |
進程線程數(shù):255 / 打印次數(shù):1000 (這里使用了第一次的實驗數(shù)據(jù))
| 多進程 | 0m17.686s | 0m17.569s | 0m17.609s | 0m17.663s | 0m17.784s | 0m17.662s |
| 多線程 | 0m17.694s | 0m17.976s | 0m17.884s | 0m17.785s | 0m18.261s | 0m17.920s |
進程線程數(shù):350 / 打印次數(shù):1000
| 多進程 | 0m23.638s | 0m23.543s | 0m24.135s | 0m23.981s | 0m23.507s | 0m23.761s |
| 多線程 | 0m23.634s | 0m23.326s | 0m23.408s | 0m23.294s | 0m23.980s | 0m23.528s |
進程線程數(shù):500 / 打印次數(shù):1000 (線程棧大小更改為1M)
| 多進程 | 0m38.517s | 0m38.133s | 0m38.872s | 0m37.971s | 0m38.005s | 0m38.230s |
| 多線程 | 0m38.011s | 0m38.049s | 0m37.635s | 0m38.219s | 0m37.861s | 0m37.995s |
進程線程數(shù):800 / 打印次數(shù):1000 (線程棧大小更改為1M)
| 多進程 | 0m48.157s | 0m47.921s | 0m48.124s | 0m48.081s | 0m48.126s | 0m48.082s |
| 多線程 | 0m47.513s | 0m47.914s | 0m48.073s | 0m47.920s | 0m48.652s | 0m48.014s |
進程線程數(shù):1000 / 打印次數(shù):1000 (線程棧大小更改為1M)
三、增加每進程/線程的工作強度的實驗
這次將程序打印數(shù)據(jù)增大,原來打印字符串為:
現(xiàn)在修改為每次打印256個字節(jié)數(shù)據(jù):
| 多進程 | 0m28.149s | 0m27.993s | 0m28.094s | 0m27.657s | 0m28.016s | 0m27.982s |
| 多線程 | 0m28.171s | 0m27.764s | 0m27.865s | 0m28.041s | 0m27.780s | 0m27.924s |
進程線程數(shù):255 / 打印次數(shù):100
| 多進程 | 2m20.357s | 2m19.740s | 2m19.965s | 2m19.788s | 2m19.796s | 2m19.929s |
| 多線程 | 2m20.061s | 2m20.462s | 2m19.789s | 2m19.514s | 2m19.479s | 2m19.861s |
進程線程數(shù):255 / 打印次數(shù):500
| 多進程 | 9m39s | 9m17s |
| 多線程 | 9m31s | 9m22s |
進程線程數(shù):255 / 打印次數(shù):2000 (實驗太耗時,因此只進行了2輪比對)
【實驗結論】
從上面的實驗比對結果看,即使Linux2.6使用了新的NPTL線程庫(據(jù)說比原線程庫性能提高了很多,唉,又是據(jù)說!),多線程比較多進程在效率上沒有任何的優(yōu)勢,在線程數(shù)增大時多線程程序還出現(xiàn)了運行錯誤,實驗可以得出下面的結論:
在Linux2.6上,多線程并不比多進程速度快,考慮到線程棧的問題,多進程在并發(fā)上有優(yōu)勢。
四、多進程和多線程在創(chuàng)建和銷毀上的效率比較
預先創(chuàng)建進程或線程可以節(jié)省進程或線程的創(chuàng)建、銷毀時間,在實際的應用中很多程序使用了這樣的策略,比如Apapche預先創(chuàng)建進程、Tomcat 預先創(chuàng)建線程,通常叫做進程池或線程池。在大部分人的概念中,進程或線程的創(chuàng)建、銷毀是比較耗時的,在stevesn的著作《Unix網(wǎng)絡編程》中有這樣 的對比圖(第一卷 第三版 30章 客戶/服務器程序設計范式):
| 0 | 迭代服務器(基準測試,無進程控制) | 0.0 | 0.0 | 0.0 |
| 1 | 簡單并發(fā)服務,為每個客戶請求fork一個進程 | 504.2 | 168.9 | 29.6 |
| 2 | 預先派生子進程,每個子進程調(diào)用accept | ? | 6.2 | 1.8 |
| 3 | 預先派生子進程,用文件鎖保護accept | 25.2 | 10.0 | 2.7 |
| 4 | 預先派生子進程,用線程互斥鎖保護accept | 21.5 | ? | ? |
| 5 | 預先派生子進程,由父進程向子進程傳遞套接字 | 36.7 | 10.9 | 6.1 |
| 6 | 并發(fā)服務,為每個客戶請求創(chuàng)建一個線程 | 18.7 | 4.7 | ? |
| 7 | 預先創(chuàng)建線程,用互斥鎖保護accept | 8.6 | 3.5 | ? |
| 8 | 預先創(chuàng)建線程,由主線程調(diào)用accept | 14.5 | 5.0 | ? |
stevens已駕鶴西去多年,但《Unix網(wǎng)絡編程》一書仍具有巨大的影響力,上表中stevens比較了三種服務器上多進程和多線程的執(zhí)行效 率,因為三種服務器所用計算機不同,表中數(shù)據(jù)只能縱向比較,而橫向無可比性,stevens在書中提供了這些測試程序的源碼(也可以在網(wǎng)上下載)。書中介 紹了測試環(huán)境,兩臺與服務器處于同一子網(wǎng)的客戶機,每個客戶并發(fā)5個進程(服務器同一時間最多10個連接),每個客戶請求從服務器獲取4000字節(jié)數(shù)據(jù), 預先派生子進程或線程的數(shù)量是15個。
第0行是迭代模式的基準測試程序,服務器程序只有一個進程在運行(同一時間只能處理一個客戶請求),因為沒有進程或線程的調(diào)度切換,因此它的速度是 最快的,表中其他服務模式的運行數(shù)值是比迭代模式多出的差值。迭代模式很少用到,在現(xiàn)有的互聯(lián)網(wǎng)服務中,DNS、NTP服務有它的影子。第1~5行是多進 程服務模式,期中第1行使用現(xiàn)場fork子進程,2~5行都是預先創(chuàng)建15個子進程模式,在多進程程序中套接字傳遞不太容易(相對于多線程), stevens在這里提供了4個不同的處理accept的方法。6~8行是多線程服務模式,第6行是現(xiàn)場為客戶請求創(chuàng)建子線程,7~8行是預先創(chuàng)建15個 線程。表中有的格子是空白的,是因為這個系統(tǒng)不支持此種模式,比如當年的BSD不支持線程,因此BSD上多線程的數(shù)據(jù)都是空白的。
從數(shù)據(jù)的比對看,現(xiàn)場為每客戶fork一個進程的方式是最慢的,差不多有20倍的速度差異,Solaris上的現(xiàn)場fork和預先創(chuàng)建子進程的最大差別是504.2 :21.5,但我們不能理解為預先創(chuàng)建模式比現(xiàn)場fork快20倍,原因有兩個:
1. stevens的測試已是十幾年前的了,現(xiàn)在的OS和CPU已起了翻天覆地的變化,表中的數(shù)值需要重新測試。
2. stevens沒有提供服務器程序整體的運行計時,我們無法理解504.2 :21.5的實際運行效率,有可能是1504.2 : 1021.5,也可能是100503.2 : 100021.5,20倍的差異可能很大,也可能可以忽略。
因此我寫了下面的實驗程序,來計算在Linux2.6上創(chuàng)建、銷毀10萬個進程/線程的絕對用時。
創(chuàng)建10萬個進程(forkcreat.c):
[cpp]?view plaincopy
創(chuàng)建10萬個線程(pthreadcreat.c):
[cpp]?view plaincopy
在我的賽揚1.5G的CPU上測試結果如下(仍采用測試5次后計算平均值):
| 0m18.201s | 0m3.159s | 12286毫秒 |
從數(shù)據(jù)可以看出,多線程比多進程在效率上有5~6倍的優(yōu)勢,但不能讓我們在使用那種并發(fā)模式上定性,這讓我想起多年前政治課上的一個場景:在講到優(yōu) 越性時,面對著幾個對此發(fā)表質(zhì)疑評論的調(diào)皮男生,我們的政治老師發(fā)表了高見,“不能只橫向地和當今的發(fā)達國家比,你應該縱向地和過去中國幾十年的發(fā)展歷史 比”。政治老師的話套用在當前簡直就是真理,我們看看,即使是在賽揚CPU上,創(chuàng)建、銷毀進程/線程的速度都是空前的,可以說是有質(zhì)的飛躍的,平均創(chuàng)建銷 毀一個進程的速度是0.18毫秒,對于當前服務器幾百、幾千的并發(fā)量,還有預先派生子進程/線程的必要嗎?
預先派生子進程/線程比現(xiàn)場創(chuàng)建子進程/線程要復雜很多,不僅要對池中進程/線程數(shù)量進行動態(tài)管理,還要解決多進程/多線程對accept的“搶” 問題,在stevens的測試程序中,使用了“驚群”和“鎖”技術。即使stevens的數(shù)據(jù)表格中,預先派生線程也不見得比現(xiàn)場創(chuàng)建線程快,在 《Unix網(wǎng)絡編程》第三版中,新作者參照stevens的測試也提供了一組數(shù)據(jù),在這組數(shù)據(jù)中,現(xiàn)場創(chuàng)建線程模式比預先派生線程模式已有了效率上的優(yōu) 勢。因此我對這一節(jié)實驗下的結論是:
預先派生進程/線程的模式(進程池、線程池)技術,不僅復雜,在效率上也無優(yōu)勢,在新的應用中可以放心大膽地為客戶連接請求去現(xiàn)場創(chuàng)建進程和線程。
我想,這是fork迷們最愿意看到的結論了。
總結
以上是生活随笔為你收集整理的多进程 VS 多线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Chrome如何离线安装crx文件
- 下一篇: Atlas200 模组拆解