多進程與多線程的優劣 與 共享內存的同步問題


通常會說:
進程之間的地址空間是獨享的,而線程是共享進程的地址空間,線程的資源比進程小,創建線程比創建進程快,線程間切換快,線程間通信快,線程資源利用率好.

下面做個補充:
1,線程掛則可能導致進程掛,穩定性差。對長時間運行的serve程序,這一點尤為重要。所以為了兼顧穩定性和性能,很多程序中采用multi-process +multi-thread.
2,線程受進程資源的限制,比如:ulimit -a可以看到的若干。
3,線程在同一進程內,方便的共享內存。進程則需做內存映射,相關的互斥量等也需要設置為進程共享。
4,同步相對復雜,不利於資源的管理和維護。

在開發經驗中你會懂得:
1)web服務器都支持master-worker多進程架構
2)apache還在worker進程里采取主線程,監聽線程,線程池的架構。
3)  lighttpd/nginx用epoll I/O復用取代Apache的多線程架構,線程切換少了,進程穩定了。
4)  I/O復用接口效率高,並發量不再受線程數限制了。
5)  多進程更有利於權限控制,通常web服務器的worker進程都會setuid到普通用戶,避免擁有過高權限受到漏洞攻擊,而master進程擁有root權限才能bind 80。 
6)  多進程有利於架構級別的擴展,更利於部署,但多線程並不是影響這個問題的關鍵因素。
7)  如果功能點不會變動或者變動小,做在線程池里讓功能更加內聚了。 但如果是一個通用模塊,把它做成可擴展的獨立進程,甚至通過程序架構設計動態庫加載,可配置回調等等,讓它為更多的項目服務,做成進程當然更合適。

另外一個問題:
在使用共享內存的時候,要注意什么?除了共享內存沒有同步機制,使用共享內存的時候,程序員要自己實現同步,還有別的要注意么?

1,創建任何東西先帶着CREAT | EXCL去創建,失敗了則直接打開,這是原子性必備的。
2,共享內存初始化之前如何同步? 設置mode的X位后開始初始化共享內存,結束后取消X位,任何進程打開共享內存后stat輪詢檢查X位是否復位,復位后才可以開始操作。
3,進程共享的mutex, cond,你應該都會用,不會用看書或者man pthread.h找接口。
4,共享內存可以做成chunk list內存塊鏈表,一般用於在共享內存中建立樹型數據結構,或者建死的多級hash表,或者循環隊列,都是可以做的。
5,其他同步機制,信號量,FIFO, 等等,反正用途比較小,看情況用。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: