出於測試目的,我編寫CPU壓力程序:它只是在M個線程中執行N個for-loops。 我用大量的線程運行這個程序,比如說200. 但是在任務管理器中我看到線程計數器沒有超過一些小值,比如說9和一個Thread.Start方法等待完成以前的運行線程。爲什麼Thread.Start方法在CPU負載過高時被阻塞?
這種行爲看起來像一個ThreadPool行爲,但我期望定期System.Threading.Thread
必須啓動無需等待某種原因。下面
代碼將重現這一問題,並有解決方法的選擇:
using System;
using System.Diagnostics;
using System.Threading;
namespace HeavyLoad
{
class Program
{
static long s_loopsPerThread;
static ManualResetEvent s_startFlag;
static void Main(string[] args)
{
long totalLoops = (long)5e10;
int threadsCount = 200;
s_loopsPerThread = totalLoops/threadsCount;
Thread[] threads = new Thread[threadsCount];
var watch = Stopwatch.StartNew();
for (int i = 0; i < threadsCount; i++)
{
Thread t = new Thread(IntensiveWork);
t.IsBackground = true;
threads[i] = t;
}
watch.Stop();
Console.WriteLine("Creating took {0} ms", watch.ElapsedMilliseconds);
// *** Comment out s_startFlag creation to change the behavior ***
// s_startFlag = new ManualResetEvent(false);
watch = Stopwatch.StartNew();
foreach (var thread in threads)
{
thread.Start();
}
watch.Stop();
Console.WriteLine("Starting took {0} ms", watch.ElapsedMilliseconds);
if (s_startFlag != null)
s_startFlag.Set();
watch = Stopwatch.StartNew();
foreach (var thread in threads)
{
thread.Join();
}
watch.Stop();
Console.WriteLine("Waiting took {0} ms", watch.ElapsedMilliseconds);
Console.ReadLine();
}
private static void IntensiveWork()
{
if (s_startFlag != null)
s_startFlag.WaitOne();
for (long i = 0; i < s_loopsPerThread; i++)
{
// hot point
}
}
}
}
案例1:如果s_startFlag創作的評論,然後啓動線程立即開始高密集的CPU工作。在這種情況下,我有一個小的併發(約9個線程)和所有的時間我抱上線啓動代碼:
Creating took 0 ms
Starting took 4891 ms
Waiting took 63 ms
案例2:但如果我創建s_startFlag,所有新的線程將等待,直到它會被設置。在這種情況下,我成功地啓動所有200個線程同時並獲得預期值:一點時間開始和很多時間線程在任務管理器中的工作,號碼是200 +:
Creating took 0 ms
Starting took 27 ms
Waiting took 4733 ms
爲什麼線程垃圾開始第一種情況?我超過了什麼樣的限制?
系統:
- 操作系統:Windows 7專業版
- 框架:NET 4.6
- CPU:英特爾酷四核Q9550 @ 2.83GHz
- RAM:8千兆
可能你正在尋找一個硬件/操作系統限制?例如,磁盤I/O肯定會有最大通道限制,這會導致一些線程被阻塞...... – code4life
此測試不涉及任何磁盤I/O。這看起來像限制「你有CPU負載95%,所以我不啓動任何線程」。但我沒有聽說過這種限制。爲什麼會發生? –
問題是,究竟是什麼導致CPU負載? CPU正在做一些事情,這就是儀器告訴你的。運行一個分析器在這一點上是非常有意義的。 – code4life