多路併發,我該選擇哪一種

前沿

通過前面關於服務器多路併發的學習,我get到了多進程、多線程、多路複用三種併發模型,那麼問題來了,在這個項目中我應該選擇哪一種模型呢?對了,先聲明一下,最近在做室內溫度監測的一個小項目,在這個項目中需要用到多路併發模型。爲了選擇一個合適的模型,我從一個宏觀角度學習一下它們之間的優缺點!

什麼是併發,什麼是並行

  • 併發:一個cpu分時處理各個進程,比如,一個cpu需要處理四個進程,對四個進程的執行時間進行分段,當在執行其中一個進程時,其他進程處於掛起狀態,當時間片到了,將此時運行的進程掛起,執行下一個進程。這也是我們常說的時間片輪轉。
  • 並行:比如有四個cpu,四個cpu可以同時執行四個進程,這就是並行。

多進程

優點

  • 程序穩定性高:子進程一旦被創建將擁有自己的進程空間,子進程之間相互獨立,子進程之間的運行狀態不會相互影響。只跟父進程的運行有關,如果父進程在子進程之前退出,子進程將變成僵死進程,不過父進程可以使用waitpid系統調用解決僵死進程問題。
  • 一路暢通:進程運行於獨立的空間中,不會限制於各種鎖的約束。
  • 編程簡單:一個fork系統調用和一個waitpid,對於像我一樣的新手入門會比較容易😄。

缺點

  • 數據交互比較麻煩:因爲進程之間資源不共享,所以當需要多個進程協同完成一個任務時,數據的交流需要使用IPC機制。小數據傳輸還好說,大數據交互就比較難以控制,各種拋bug。
  • 耗內存,進程個數受限制:一個進程分配一個用戶空間,內核負擔隨進程個數的增加而增加,過多的進程上下文切換,無疑會影響cpu運行效率,因此 ulimit -u可以查看進程上限。
  • 資源分配和回收系統開銷巨大。

多線程

優點

  • 通信高效:可以使用全局變量來進行數據共享,不用IPC通信機制,進程不需要在用戶空間和內核空間頻繁切換,通信效率較高。
  • 資源利用率高:比如此時cpu中運行着一個進程,這個進程需要完成文件的讀取和處理文件,當讀取文件的時候,cpu等待文件讀取完成再處理文件,爲了充分利用cpu資源,我們可以在一個進程中設計兩個線程,一個線程用於讀文件,一個線程用於處理文件。
  • 一定程度上資源分配和回收容易:線程是一個進程的執行路徑,多個線程位於同一進程空間,系統不需爲線程重新開闢空間,線程任務執行完成後可自動銷燬。不過線程具有自己獨立的堆棧空間,線程裏面的局部變量不共享。

缺點

  • 當使用一些臨界資源時,線程容易阻塞,等待另一線程釋放資源,就像上班高峯期堵車一樣。
  • 容易產生死鎖:長時間得不到所需要得資源的話,容易產生死鎖。
  • 數據髒讀:上一個線程由於某種原因對該資源沒有處理完畢就退出,後一個線程就會讀取到預期之外的數據。
  • 程序可靠性:線程會影響整個程序的運行,一個線程出現bug,可能會導致整個進程出現問題。
  • 線程會消耗cpu的資源,所以cpu對線程的數量有限制,/usr/include/bits/local_lim.h查看。具體限制多少相對系統而言,

多路複用

select

優點

  • 同一進程同一線程中可以處理多個客戶端請求,減少cpu時間片分配,減少系統開銷。
  • 跨平臺,select是windows下常見的io管理機制。

缺點

  • 內存拷貝:調用select時,將文件描述符集合從用戶態拷貝到內核態,內核開銷比較大。
  • 遍歷fd:拷貝到內核之後,還要在內核將fd集合遍歷,將該進程添加到等待隊列中。有數據到來後又將文件描述集從內核拷貝到用戶空間,再次遍歷fd集合,判斷是哪一個fd可讀。用戶空間和內核空間頻繁切換。
  • 最大的可處理的文件描述符是1024。

poll

poll是對select的升級,它沒有最大文件描述符個數的限制,poll返回時不會對文件描述符數組進行清空,所以不要重複初始化文件描述符數組初始化,另外poll增加了events和revents,對每個文件描述符貼上標籤,返回時便於檢查和判斷是什麼事件發生。

epoll

epoll又是poll的增強版本,和poll不同的是返回的是獲取事件的文件描述和fd個數,在判斷定位哪個文件描述可讀的時候,不需要遍歷整個文件描述符集合,只需遍歷返回的那個數組,大大減小了時間複雜度,避免了大量無用的操作。epoll可處理百萬級別的客戶端請求,epoll已經成爲了目前實現高性能網絡服務器的必備技術,在大數據、高併發、集羣的一些應用中,select和poll的用武之地越來越有限,風頭已經被epoll佔盡。

總結

一路學習下來,各有各的優勢和缺陷,使用哪種模型在於特定的場景,在這個項目中,爲了更好地理解多路複用,我將採取多路複用模型,而且I/O多路複用是在單一進程的上下文中的,因此每個邏輯流程都能訪問該進程的全部地址空間,加之多路複用是事件驅動模型的,所以開銷比多進程和多線程低得多,而在IO多路複用中epoll模型比較完善,所以最後決定使用epoll模型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章