0

以下のコードでは、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);
            }
        }
    }        
}
4

1 に答える 1

0

愚かな私:)私はロックで仕事をしていた!!! もちろん、これらのメソッドをロックから外すと、問題は解決しました。

    private static void ConcurrentMethod()
    {
        lock (m_Locker)
        {
            while (!flag_GO) Monitor.Wait(m_Locker);                
        }
        TestWhatEverYouWant();
        IamDone();
    }

そして、私は希望の出力を得ました!

OverAll Elapsed Time: 1004
Individual Elapsed Time: 1000
Individual Elapsed Time: 999
于 2012-11-29T07:06:50.127 に答える