1樓:uuchen
select poll epoll從根本上說就是講io操作阻塞在如上函式上以達到io復用的目的,從而在乙個執行緒上處理多個io。
2樓:dong
簡單的執行緒池模型為每個連線建立乙個執行緒,當有1k個空閒長連線,那麼你就需要1k個執行緒才能處理。
epoll+執行緒池模型則是IO執行緒處理IO收發,當IO執行緒收到乙個完整的請求,然後把請求交給執行緒池處理,執行緒池處理完成之後,結果交由IO執行緒傳送回客戶端。因此1k各空閒長連線只需幾個執行緒就能處理,大大優於前者。
假設實際負載較大,同時有100個請求到達,那麼10執行緒的epoll+執行緒池的處理方案中,這100個請求會排隊,最終都能夠處理完。因此epoll+執行緒池的方案大大優於執行緒池方案。
3樓:羅然
瓶頸在於IO密集度。
執行緒池你開10個執行緒當然可以一上來全部accept阻塞住,這樣客戶端一連上來便會自動啟用乙個執行緒去處理,但是設想一下,如果10個執行緒全部用掉了,第11個客戶端就會發生丟棄。這樣為了實現」高併發「你得不斷加大執行緒池的數量。這樣會帶來嚴重的記憶體占用和執行緒切換的時延問題。
於是前置事件輪詢設施的方案就應運而生了,
主線程輪詢負責IO,作業交給執行緒池。
在高併發下,10W個客戶端上來,就主線程負責accept,放到佇列中,不至於發生沒有及時握手而丟棄掉連線的情況發生,而作業線程從佇列中認領作業,做完回覆主線程,主線程負責write。這樣可以用極少的系統資源處理大數量連線。
在低併發下,比如2個客戶端上來,也不會出現100個執行緒hold住在那從而發生系統資源浪費的情況。
4樓:
你的「執行緒池模型」是怎樣的?主線程 select + accept,然後發給工作執行緒去 recv / process / send?如果是這樣的話,你執行緒池模型本身就用錯了:)
正確實現基本執行緒池模型的核心:
主線程負責所有的 I/O 操作,收齊乙個請求所有資料之後如果有必要,
交給工作執行緒進行處理 。處理完成之後,把需要寫回的資料還給主線程去做寫回 / 嘗試寫回資料直到阻塞,然後交回主線程繼續。
這裡「如果有必要」的意思是:經過測量,確認這個處理過程中所消耗的 CPU 時間(不包括任何 I/O 等待,或者相關的 I/O 等待操作無法用 epoll 接管)相當顯著。如果這個處理過程(不包含可接管的 I/O 操作)不顯著,則可以直接放在主線程裡解決。
這個「必要」與否的前提不過三個詞:假設,分析,測量。
所以,乙個正確實現的執行緒池環境鐘,用 epoll + non-blocking I/O 代替 select + blocking I/O 的好處是,處理大量 socket 的時候,前者效率比後者高,因為前者不需要每次被喚醒之後重新檢查所有 fd 判斷哪個 fd 的狀態改變可以進行讀寫了。
世間本無魔法。
java執行緒池(newFixedThreadPool)執行緒消失疑問?
原始碼看不看不重要,建議詳細看一下 jdk 自帶執行緒池的文件。jdk 自帶執行緒池中線程何時銷毀是由執行緒池的多個引數綜合決定的,所以使用者提交的執行緒中是否丟擲了異常對執行緒池中線程的銷毀是沒有影響的。如果使用者提交的執行緒丟擲了異常會退出使用者執行緒的 run 方法,執行執行緒是否需要銷毀由執...
Java執行緒池應該如何使用?
半圓學社 執行緒池應該在程式啟動的時候進行初始化,中間只要不出現異常或沒有特殊需求則可以不關閉。執行緒的建立和銷毀要花費時間,使用執行緒池可以復用執行緒,執行緒池可以設定核心執行緒數量,核心執行緒處理完任務後,並不會銷毀,而是保持空閒直到下一次有執行緒需要建立時,直接執行任務。 隨心隨意 說點我的理...
Node中libuv的I O執行緒池與PHP之類建立的執行緒有啥區別?
碼農投資筆記 IO分為磁碟IO與網路IO,磁碟IO確實得由libuv執行緒池中的執行緒去阻塞執行,但是網路IO就不用了,網路IO這一塊linux底層是epoll,windows是IOCP,都是採用IO多路復用技術,即事件監聽。libuv中的執行緒只需要把網路IO的socket註冊到epoll IOC...