c#中的单次旋转有多长?我想知道的是有一个具有spinCount参数的ManualResetEventSlim,我想知道每次旋转的时间是多少,或者它是如何工作的?我知道,对于短等待而言,旋转比内核等待更有效。所以我只是想看看我应该为这个通常需要2-10秒的工作设置这个值。
答案 0 :(得分:29)
构造函数中的spinCount
参数与进行旋转等待所花费的毫秒数之间没有相关性。
以下是它的工作原理。 MRES使用此spinCount
参数来独立于Thread.SpinWait
进行自己的等待例程。
Thread.Yield
和Thread.SpinWait
之间交替。对Thread.SpinWait
的调用以Environment.ProcessorCount * 4
的旋转开始,然后在每次连续调用时大约翻倍。Thread.Sleep(1)
整除。Thread.Sleep(0)
。Thread.Yield
。CancellationToken
。所以你可以看到在MRES的定制旋转程序中有一个相当复杂的歌舞。并且算法可以从版本更改为版本。实际上没有办法预测每次旋转会持续多长时间。
如果您的典型等待时间是2-10秒,那么您的代码几乎肯定会通过Monitor.Wait
和Monitor.Pulse
协调进行内核级等待,因为spinCount
参数仅限于反正是2047年。
另外,2-10秒是很长一段时间。你真的想旋转这么久吗?
答案 1 :(得分:12)
旋转计数意味着很小。默认值为10(如果在单个处理器上运行,则为1)。如果使用允许指定旋转计数的构造函数,则允许的最大值为2047.如果事件没有很快发出信号,则ManualResetEventSlim使用常规事件句柄等待。正如@HenkHolterman所说,所涉及的时间远远小于秒。我们说的是周期,而不是几秒甚至几毫秒。
http://msdn.microsoft.com/en-us/library/5hbefs30.aspx
在.NET Framework版本4中,您可以使用 System.Threading.ManualResetEventSlim类以获得更好的性能 当等待时间预计很短时,事件发生时 不跨过程边界。 ManualResetEventSlim使用忙碌旋转 在等待事件发出信号的短时间内。什么时候 等待时间短,旋转可以比等待便宜得多 通过使用等待句柄。但是,如果事件没有发出信号 在一段时间内,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本质上将处理器置于一个非常紧密的循环中 迭代参数指定的循环计数。持续时间 因此等待取决于处理器的速度。