以下のコードでは、2人のワーカーを同時に起動して、全体の経過時間と個々の経過時間が一致するようにしています。私は、すべての経過時間で1000ミリ秒(+たとえば3ミリ秒の遅延)、すべてのワーカーの個々の経過時間は1000ミリ秒になると予想していました。
しかし、すべてのワーカーが順番に実行されているかのように出力を取得しました。
OverAll Elapsed Time: 2001
Individual Elapsed Time: 1000
Individual Elapsed Time: 999
私が欠けているものを説明してもらえますか?
class Program
{
static int m_NumberOfWorkers = 2;
static readonly object m_Locker = new object();
static bool flag_GO = false;
static Stopwatch m_OverAllStopwatch = new Stopwatch();
static ConcurrentBag<Stopwatch> m_bagIndividualStopwatch = new ConcurrentBag<Stopwatch>();
static int m_CompletedWorkers = 0;
static void Main(string[] args)
{
// Create Workers
List<Thread> lstThreads = new List<Thread>();
for (int i = 0; i < m_NumberOfWorkers; ++i)
{
lstThreads.Add(new Thread(ConcurrentMethod));
}
// Start Workers
for (int i = 0; i < lstThreads.Count; ++i)
{
lstThreads[i].Start();
}
m_OverAllStopwatch.Start();
// Signal all workers
lock (m_Locker)
{
flag_GO = true;
Monitor.PulseAll(m_Locker);
}
// Wait all workers to finish
for (int i = 0; i < lstThreads.Count; ++i)
{
lstThreads[i].Join();
}
Console.Read();
}
private static void ConcurrentMethod()
{
lock (m_Locker)
{
while (!flag_GO) Monitor.Wait(m_Locker);
TestWhatEverYouWant();
IamDone();
}
}
private static void TestWhatEverYouWant()
{
Stopwatch stopWatch = Stopwatch.StartNew();
Thread.Sleep(1000);
stopWatch.Stop();
m_bagIndividualStopwatch.Add(stopWatch);
}
private static void IamDone()
{
Interlocked.Increment(ref m_CompletedWorkers);
// Summarize results if all workers are done
if (Interlocked.CompareExchange(ref m_CompletedWorkers, 0, m_NumberOfWorkers) == m_NumberOfWorkers)
{
m_OverAllStopwatch.Stop();
Console.WriteLine("OverAll Elapsed Time: {0}", m_OverAllStopwatch.ElapsedMilliseconds);
foreach (Stopwatch stopWatch in m_bagIndividualStopwatch)
{
Console.WriteLine("Individual Elapsed Time: {0}", stopWatch.ElapsedMilliseconds);
}
}
}
}