在ManualResetEventSlim中单次旋转多长时间

本文关键字:长时间 旋转 单次 ManualResetEventSlim | 更新日期: 2023-09-27 18:32:19

c#中的单次旋转有多长?我想知道的是有一个具有spinCount参数的ManualResetEventSlim,我想知道每次旋转的时间(以毫秒为单位)或它是如何工作的?我知道旋转对于短时间等待比内核等待更有效。所以我只是想看看我应该为通常需要 2-10 秒的工作设置这个值。

在ManualResetEventSlim中单次旋转多长时间

构造函数中的spinCount参数与执行旋转等待所花费的毫秒数之间没有相关性。

这是它的工作原理。MRES 使用此spinCount参数通过自己的等待例程,独立于Thread.SpinWait

  • 前 10 次迭代在调用 Thread.YieldThread.SpinWait 之间交替。对Thread.SpinWait的调用从旋转Environment.ProcessorCount * 4开始,然后在每次连续调用时大约翻倍。
  • 此后每次迭代可被 20 次调用整除Thread.Sleep(1) .
  • 否则,那些可以被 5 整除的调用Thread.Sleep(0) .
  • 否则调用Thread.Yield
  • CancellationToken在 100 次迭代后每 10 次迭代检查一次。

因此,正如你所看到的,在MRES的定制纺纱程序中有一个相当复杂的歌舞。并且算法可能会因版本而异。真的没有办法预测每次旋转会持续多长时间。

如果您的典型等待时间为 2-10 秒,那么您的代码几乎肯定会通过 Monitor.WaitMonitor.Pulse协调进行内核级等待,因为无论如何spinCount参数都限制为 2047。

另外,2-10秒是很长的时间。你真的想旋转那么久吗?

自旋计数应该很小。默认值为 10(如果在单个处理器上运行,则为 1)。如果使用允许您指定旋转计数的构造函数,则允许的最大值为 2047。如果事件信号不是很快,ManualResetEventSlim 将使用常规事件句柄等待。正如@HenkHolterman提到的,所涉及的时间远远小于秒。我们谈论的是周期,而不是几秒钟甚至几毫秒。

http://msdn.microsoft.com/en-us/library/5hbefs30.aspx

在 .NET Framework 版本 4 中,可以使用 系统.线程.手动重置事件苗条类以获得更好的性能 预计等待时间非常短,以及事件何时 不跨越进程边界。手动重置事件苗条使用繁忙的旋转 在等待事件发出信号的短时间内。什么时候 等待时间短,纺纱比等待便宜得多 通过使用等待句柄。但是,如果事件没有发出信号 在一定时间内,ManualResetEventSlim诉诸于一个 常规事件句柄等待。

http://msdn.microsoft.com/en-us/library/ee722114.aspx

在多核计算机上,当不应保留资源时 长时间等待可能会更有效率 线程在用户模式下旋转几十或几百个周期, ,然后重试以获取资源。资源是否可用 旋转后,您已经节省了数千个周期。如果 资源仍然不可用,那么您只花了几个周期 并且仍然可以进入基于内核的等待。

编辑:直接回答您的问题,单次旋转的时间长度无法明确回答,因为它取决于运行它的硬件。http://msdn.microsoft.com/en-us/library/system.threading.thread.spinwait(v=vs.95).aspx

SpinWait本质上将处理器置于一个非常紧密的循环中,与 迭代参数指定的循环计数。持续时间 因此,等待取决于处理器的速度。