一個 CPU 核 開多少個 線程 比較合適 ?
這是一個 線程池 的 問題 。
我之前也 反對 過 線程池, 因為我認為 線程池 影響了 對 用戶 的 實時響應性 。
我也認為, 分時 (對 CPU 資源的分配) 應該由 操作系統 來做就行, 不需要 再 畫蛇添足 。
不過, 現在 主流的應用 好像都在用 線程池 , 比如 Asp.net ,對每個請求的處理, 好像是放到 線程池 里執行的, 所以 經常可以看到這樣的現象, Asp.net 里 處理請求的 線程 的 線程號 是 重復的, 比如 處理 第一個請求 的 線程號 是 2, 處理 第三個請求 的 線程號 也是 2 , 處理 第 n 個請求, 第 x, y, z 個請求 的 線程號 也是 2 …… 。
所以, 考慮到 創建線程 的 性能花費 還是 挺可觀 的, 算了, 還是 隨大流 吧 。 我們也用 線程池 。
不過 “創建線程 的 性能花費 還是 挺可觀 的” 這是 據說, 我沒有具體去研究過 。
我之前寫過一篇文章 《自己實現一個線程池》 https://www.cnblogs.com/KSongKing/p/9803935.html , 可以看看 。
接下里進入主題, 一個 CPU 核 開多少個 線程 比較合適 ?
如果我們寫過 從網頁上抓取內容 的 程序, 就會有一些經驗 :
比如, 當 線程 開到 100 個 以上時, 效率 不升反降; 而 100 個線程 的 效率 和 60 個線程 一樣, 60 個線程 和 40 個 也差不多 。
So ……
我的 CPU 是 2 核 4 線程, 所以這樣評估下來的話, 1 個 核 開 10 ~ 20 個 線程 差不多 。
這個 核 沒有算 超線程, 超線程 大概可以算 半個 核, 大家可以自己評估一下 。 哈哈哈
之前在 QQ 群 里討論相關問題時, 有網友說, “線程切換 …… 一個 yield 下來, 就是 15 毫秒(ms) 。”
這個 yield 是什么意思, 我不知道, 你們去問他吧 …… 哈哈哈哈
有 網友說 “像 雲平台 的 對象存儲 一樣, 一個 CPU(核)開一個 線程 就行了”,
這是 一種 理想狀況 。
對於 一般的 業務系統, 普遍的有 等待 其它進程 的 操作, 比如 等待 IO, 等待 數據庫 返回結果 。
所以, 通常 根據 自己的 應用 的 實際情況,可以有一個 在 多數情況下的 最優解, 即 最優 線程池 Size 。
自己應用 的 實際情況, 是指 用戶量(並發量) 數據庫等待時間 IO 等待時間 等 。
根據這些 可以 評估出一個 適當的 線程池 Size 。
有 網友 問, “有算法嗎?”
我 臨時 拼湊了 一個 算法, 如果 並發量 是 每秒 200 個, 數據庫 等待 的 平均時間 是 10 毫秒, 這樣 理論上, 1 個線程 1 秒鍾 可以處理 1秒 / 10 毫秒 = 100 個請求, 即 100 個 請求 / 秒 。
那么, 200 個 請求 的話 就需要 200 / 100 = 2 個線程,
當然, 這是 在 1 秒 內 輪流執行的, 最壞 的 情況 用戶 需要 等待 1 秒 。
可以 再適當的 增加一些 線程數量 來 提高 並發水平,
比如 增加到 5 個 線程, 這樣 最壞的情況 用戶 只需要等待 1/5 秒 = 0.2 秒 。
