簡體   English   中英

Parallel.ForEach不使用所有可用的線程池線程

[英]Parallel.ForEach doesn't make use of all available thread pool threads

為什么當我運行以下示例時,我是否只讓Parallel.ForEach運行的線程數等於我機器上的核心數? 我以為Parallel.ForEach給你的線程池線程大約有1000個?

            int threads1;
            int threads2;

            ThreadPool.GetAvailableThreads(out threads1,out threads2);
            var list = Enumerable.Range(1, 200);
            var po = new ParallelOptions
            {
                MaxDegreeOfParallelism = 100
            };

            Parallel.ForEach(list, po, x =>
                {
                    Console.WriteLine("Thread:" + Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(1000);
                });

我在這里錯過了什么嗎?

Parallel.ForEach使用托管線程池來調度並行操作。 線程數由ThreadPool.SetMinThreadsThreadPool.SetMaxThreads設置。 默認情況下,最小線程數設置為系統上的處理器數。

為了最小化系統資源的使用,池線程的數量保持盡可能低。 當所有池線程忙於執行操作時,調度程序會逐漸生成新線程。

MaxDegreeOfParallelism值通常用於防止Parallel.For調度超過指定數量的任務。 在長計算的情況下,當沒有使用比核心數更多的線程的意義時,它是有用的。

如果通過增加休眠時間Thread.Sleep(100000);修改代碼Thread.Sleep(100000); ,您將看到新線程的創建。

如果你調用ThreadPool.SetMinThreads(100, 100); Parallel.ForEach之前,您將看到所有100操作同時啟動。

如果線程數不超過處理核心數,您將獲得最佳性能。

每個核心一次只能處理一個線程。 如果除了核心更多線程,操作系統必須切換線程之間。 上下文切換是一項昂貴的操作,您應該盡量避免在多線程應用程序中使用它。

如果您執行的操作是IO綁定的,則應使用Task而不是Paraller.For 斯科特漢塞爾曼的博客很好地解釋了這一點。

Parallel.For線程管理的細節在Andrey Nasonov的回答中有詳細解釋,所以我不再重復了。

如果你想了解更多關於線程,TPL和異步I / OI推薦CLR通過C#book

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM