linux/unix socket編程並發時什麼時候用進程(fork),什麼時候用線程(池)?


無論是多線程還是多進程都不適合高並發的網路服務,現在的主流方式是在單進程中使用基於非同步IO的事件框架,某些語言中會考慮使用協程。C10k problem 是一篇可以參考的維基文檔。描述了在高並發的情況下普遍的做法。

在目前的情況下,線程和進程一般都僅僅依照 CPU 核心的數量開啟「有限個」,例如 4 核心的 CPU 可以開 4 個或者略多於 4 個進程,其中每個進程使用非同步IO可以服務成千上萬的請求。

一千個線程比一千個進程更省資源,但四個線程跟四個進程就未必了。在「進程數等於CPU核心數量」的這個尺度下,線程相比進程沒有太多優勢。所以可以簡單的理解為沒有特別的需要不要使用線程(除了在某些特定的場合下,例如撰寫 UI 等等線程數量預先可以確定的應用)。

就題主所問的這個場合,你無法預期並發數量能達到什麼程度,還是用非同步 IO 配每核心一個進程吧,否則你的伺服器在負載增加之後基本上都會假死。


學習下原理,工程上還是用框架吧,否則有踩不完的坑。


傳統上採取進程的好處在於進程有天然的隔離性(isolation),一個進程crash不會影響其他的進程。由於直接用C/C++開發的原生服務端程序很容易跑飛掉,所以用進程比用線程更保險,不會因為服務一個客戶端的時候有crash bug把其他無辜的socket connection牽連進來

但是隨著服務端編程越來越多地使用高度託管(managed)的安全得多的編程系統,如Java、.NET、Erlang等,已經不會出現crash掉進程的情況,最多是拋出的異常終止單個線程而已。這時進程的意義就不大了,線程甚至纖程開始成為主流


《Linux 多線程服務端編程》第3章和第6.6節。


能用多進程的情況下絕不用多線程;
能用多線程的情況下就不考慮非同步;
有現成的非同步框架就絕不考慮手寫。


推薦閱讀:

ssh遠程登陸有時候正常,有時候顯示:ssh_exchange_identification: Connection closed by remote host,這是什麼原因?
魅族會不會考慮 Ubuntu 系統?
關於Socket API的設計?
Linux 下 socket 編程有什麼需要注意的?
如何用 Nginx 配置透明 HTTP 和 HTTPS 代理?

TAG:編程 | Linux | 伺服器 | Socket | 多線程 |