首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ManualResetEventSlim中单次旋转有多长

在ManualResetEventSlim中单次旋转有多长
EN

Stack Overflow用户
提问于 2012-04-25 03:39:11
回答 2查看 4.5K关注 0票数 14

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-25 04:44:09

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

下面是它的工作原理。MRES使用此spinCount参数独立于Thread.SpinWait执行自己的等待例程。

  • 前10次迭代在调用Thread.YieldThread.SpinWait之间交替进行。对call.
  • Thereafter的调用开始于Environment.ProcessorCount * 4的旋转,然后在每个连续的调用上大约加倍每个迭代可被20整除的调用那些可被5个调用整除的调用Thread.Sleep(0).
  • Otherwise Thread.Yield被调用。
  • CancellationToken在100之后每10次迭代检查一次。

因此,正如您所看到的,在MRES的自定义旋转例程中有一个相当复杂的歌舞。并且算法可以从一个版本到另一个版本。真的没有办法预测每一次旋转会持续多久。

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

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

票数 32
EN

Stack Overflow用户

发布于 2012-04-25 04:34:07

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

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

在.NET框架版本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实际上将处理器置于一个非常紧密的循环中,循环计数由迭代参数指定。因此,等待的持续时间取决于处理器的速度。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10304854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档