简体   繁体   English

c#中信令线程的性能

[英]Performance of signaling threads in c#

I've been attempting to understand how long it takes to "wake" a thread who is waiting on a blocking construct like AutoResetEvent - from what I understood after reading multiple discussions is that windows has some kind of internal clock which "ticks" every 15.6ms (or so) and then decide which threads are scheduled to run next, so I would expect that the time difference between signaling a thread until that thread wakes up would take a random time between 0-15.6ms. 我一直在试图理解“唤醒”正在等待像AutoResetEvent这样的阻塞构造的线程需要多长时间 - 从我在阅读多个讨论后理解的是,windows有某种内部时钟,每15.6“滴答”一次ms(左右)然后决定调度哪些线程接下来运行,所以我希望在线程发出信号直到该线程唤醒之间的时间差需要0-15.6ms之间的随机时间。 So I wrote this small program to test my theory: 所以我写了这个小程序来测试我的理论:

static void Main(string[] args)
        {
            double total = 0;
            int max = 100;
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            for (int i = 0; i < max; i++)
            {                
                AutoResetEvent eventHandle = new AutoResetEvent(false);
                double time1 = 0;
                double time2 = 0;
                Thread t1 = new Thread(new ThreadStart(() => time1 = f1(stopwatch, eventHandle)));
                Thread t2 = new Thread(new ThreadStart(() => time2 = f2(stopwatch, eventHandle)));
                t1.Start();
                t2.Start();
                t1.Join();
                t2.Join();
                double diff = time2 - time1;
                total += diff;
                Console.WriteLine("Diff = " + diff.ToString("F4"));
            }
            double avg = total / max;
            Console.WriteLine("Avg = " + avg.ToString("F4"));

            Console.ReadKey();
        }

        static double f1(Stopwatch s, AutoResetEvent eventHandle)
        {
            Thread.Sleep(500);
            double res = s.Elapsed.TotalMilliseconds;
            eventHandle.Set();
            return res;
        }

        static double f2(Stopwatch s, AutoResetEvent eventHandle)
        {
            eventHandle.WaitOne();
            return s.Elapsed.TotalMilliseconds;                        
        }

To my surprise the average wake-up time was around 0.05 milliseconds - so obviously i'm missing something but I don't know what... 令我惊讶的是,平均唤醒时间约为0.05毫秒 - 显然我错过了一些东西,但我不知道是什么......

No, 15.625 msec is the period of the clock tick interrupt. 不,15.625毫秒是时钟滴答中断的周期。 Which lets the scheduler interrupt a thread if it has been running without blocking and the scheduler decides that another thread should get a turn. 这使调度程序在没有阻塞的情况下中断线程并且调度程序决定另一个线程应该转向时中断线程。

Threads that block will be pre-empted at their WaitXxx() call. 阻止的线程将在WaitXxx()调用时被抢占。 Or Sleep() call. 或者Sleep()通话。 Regardless of the clock tick interrupt. 无论时钟滴答中断。

Notable as well is that a sleeping thread can only resume running at a clock interrupt tick, the reason that Thread.Sleep(1) in fact sleeps for 15.6 msec. 值得注意的是,睡眠线程只能在时钟中断标记处恢复运行,这是Thread.Sleep(1)实际上休眠15.6毫秒的原因。 Timers, DateTime.Now and Environment.TickCount also have that accuracy, the clock is incremented by the interrupt. 定时器,DateTime.Now和Environment.TickCount也具有该精度,时钟由中断递增。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM