Ana*_*yal 70 c# multithreading
是否有效率
SpinWait.SpinUntil(() => myPredicate(), 10000)
Run Code Online (Sandbox Code Playgroud)
超时10000毫秒
要么
Thread.Sleep
在相同条件下使用轮询是否更有效例如,以下SleepWait
函数的行:
public bool SleepWait(int timeOut)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (!myPredicate() && stopwatch.ElapsedMilliseconds < timeOut)
{
Thread.Sleep(50)
}
return myPredicate()
}
Run Code Online (Sandbox Code Playgroud)
我担心如果我们谈论超过1秒的超时,SpinWait的所有收益可能都不是一个好的使用模式?这是一个有效的假设吗?
您更喜欢哪种方法?为什么?还有另一种更好的方法吗?
更新 - 变得更具体:
有没有办法让BlockingCollection Pulse在达到有界容量时成为睡眠线程?正如Marc Gravel建议的那样,我宁愿避免忙碌等待.
Moo*_*ght 125
在.NET 4中SpinWait
,在屈服之前执行10次迭代的CPU密集型旋转.但是在每个周期之后它不会立即返回给调用者; 相反,它调用Thread.SpinWait
通过CLR(本质上是OS)旋转一段时间.该时间段最初为几十纳秒,但每次迭代加倍,直到10次迭代完成.这使得旋转(CPU密集型)阶段所花费的总时间的清晰度/可预测性成为可能,系统可以根据条件(核心数等)进行调整.如果SpinWait
在旋转产生阶段停留太长时间,它将定期休眠以允许其他线程继续进行(有关更多信息,请参阅J. Albahari的博客).这个过程保证让核心忙碌......
因此,SpinWait
将CPU密集型旋转限制为设定的迭代次数,之后它会在每次旋转(通过实际调用Thread.Yield
和Thread.Sleep
)时产生时间片,从而降低其资源消耗.如果是这种情况,它还将检测用户是否正在运行单个核心机器并在每个周期产生.
随着Thread.Sleep
线程被阻止.但就CPU而言,这个过程不会像上面那样昂贵.
Mar*_*ell 46
在最好的办法是有一些机制来主动检测的东西变成真正的(而不是被动地轮询它已经成为真正的); 这可能是任何类型的等待句柄,或者一个Task
用Wait
,也许一个event
,你可以订阅扯去自己.当然,如果你做那种"等到事情发生",那仍然不如仅仅将下一部分工作作为回调完成那样有效,这意味着:你不需要使用线程来等待.Task
有ContinueWith
这个,或者你可以event
在它被解雇时做的工作.这event
可能是最简单的方法,具体取决于上下文.Task
然而,已经提供了你在这里谈论的大部分内容,包括"等待超时"和"回调"机制.
是的,旋转10秒并不是很好.如果你想使用类似当前代码的东西,并且你有理由期望短暂的延迟,但是需要允许更长的延迟 - 也许SpinWait
是(比方说)20ms,并Sleep
用于其余的?
重新评论; 这是我如何勾选"它是完整的"机制:
private readonly object syncLock = new object();
public bool WaitUntilFull(int timeout) {
if(CollectionIsFull) return true; // I'm assuming we can call this safely
lock(syncLock) {
if(CollectionIsFull) return true;
return Monitor.Wait(syncLock, timeout);
}
}
Run Code Online (Sandbox Code Playgroud)
用,在"放回集合"代码:
if(CollectionIsFull) {
lock(syncLock) {
if(CollectionIsFull) { // double-check with the lock
Monitor.PulseAll(syncLock);
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
59458 次 |
最近记录: |