我有很多關于Parallel.ForEach回圈操作的問題,尤其是關于ParallelOptions.MaxDegreeOfParallelism屬性的設定。
我的計算機的 CPU 是四核,具有 8 個邏輯處理器。
對我來說,以下應該是可以并行執行的最大可能行程數,畢竟我有 8 個執行緒可用:
ParallelOptions parallelOptions = new()
{
MaxDegreeOfParallelism = Environment.ProcessorCount //8,
};
考慮以下代碼。這只是圍繞 300 個 uri 的串列進行迭代,并對回應執行“某些操作”:
List<string> uriList = new List<string>();
for (int i = 0; i < 300; i )
{
uriList.Add(uri);
}
HttpClient httpClient = new HttpClient();
ParallelOptions parallelOptions = new()
{
MaxDegreeOfParallelism = uriList.Count(),
};
await Parallel.ForEachAsync(uriList, parallelOptions, async (uri, token) =>
{
var response = await httpClient.GetStringAsync(uri);
if (response != null)
{
ProcessResponse(response);
}
});
請注意,該MaxDegreeOfParallelism屬性設定為uriListie 300 的大小,而不是我的物理硬體 8 可用的執行緒數。此代碼有效,我不知道為什么將MaxDegreeOfParallelism屬性設定為“有效”。
問題:
該
MaxDegreeOfParallelism屬性可以指定為任何數字,但并發操作的最大數量只會與硬體的可用執行緒數一樣高?該
MaxDegreeOfParallelism屬性可以看作是設定同時執行多少并行“批次”作業?例如,迭代一個包含 16 個專案的串列并MaxDegreeOfParallelism設定為“8”會導致兩批“8”并發呼叫?如果
MaxDegreeOfParallelism未設定該屬性,則默認情況下將設定可用的最大執行緒數?在異步的情況下,
Parallel.Foreach處理請求會等到先前的“批處理”呼叫回傳嗎?或者,當await遇到一個并且執行緒被“釋放”時,另一個專案可以uriList在回圈中開始它的邏輯步驟嗎?屬性設定是否有“最佳位置”
MaxDegreeOfParallelism?
uj5u.com熱心網友回復:
您的代碼可以按需要作業,因為大部分 I/O 系結異步操作不使用執行緒。
默認情況下Parallel,方法族安排作業ThreadPool。您可以通過提供 custom 來自定義安排作業的位置TaskScheduler,但這很少需要。在大多數情況下,使用ThreadPool是可以的。ThreadPool可以創建比處理器/內核數大得多的執行緒數。如果需要,它可以創建數千個執行緒1。所有這些執行緒將共享機器的可用處理器/內核。如果活動(非睡眠)執行緒多于內核,作業系統會將可用的處理能力分配給所有執行緒,因此所有執行緒都將獲得它們的時間片并取得進展。
MaxDegreeOfParallelism不適用于批處理。當一個元素的處理完成時,立即開始另一個元素的處理。在開始下一批之前,它不會等待上一批完成。
的默認值MaxDegreeOfParallelism等于Parallel.ForEachAsync,Environment.ProcessorCount所有其他Parallel方法的默認值等于 -1,這意味著無限并行。我的建議是始終指定MaxDegreeOfParallelism何時使用任何Parallel方法,這與Microsoft 推薦的不同。
受MaxDegreeOfParallelismCPU 限制的操作的最佳選擇是Environment.ProcessorCount,但如果作業負載不平衡,超額訂閱可能會有所幫助。這Parallel.ForEachAsync通常用于 I/O 系結的異步操作,其中最佳點取決于遠程服務器的功能或網路的帶寬。
1有關 的行為的更多詳細資訊ThreadPool,您可以查看此處。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/520356.html
