我错过了一次启动所有工人的方法?

时间:2012-11-29 06:31:43

标签: multithreading c#-4.0 concurrency

我是多线程新手。如果我问的是非常愚蠢的问题,请跟我说。

在下面的代码中,我试图同时启动两个工作人员,以便超过所有已用时间和经过的个人相互匹配。我期待所有经过的时间超过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);
            }
        }
    }        
}

1 个答案:

答案 0 :(得分: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