我如何才能确保只有一个线程会做什么? [英] How can I make sure that exactly one thread will do something?
本文介绍了我如何才能确保只有一个线程会做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个项目添加到一个无锁队列多个线程。
的项目,然后由另外一个线程处理。
I have multiple threads which add items to a lock-free queue.
The items are then processed by another thread.
在生产者线程,我要揭开序幕消费者线程,的但只有当它尚未运行或拉开帷幕的。
In the producer threads, I need to kick off the consumer thread, but only if it's not already running or kicked off.
具体做法是:
public void BeginInvoke(Action method)
{
//This runs on multiple background threads
pendingActions.Enqueue(method);
if (ProcessQueue hasn't been posted)
uiContext.Post(ProcessQueue, null);
}
private void ProcessQueue(object unused)
{
//This runs on the UI thread.
Action current;
while (pendingActions.TryDequeue(out current))
current();
}
我使用.net 3.5,而不是4.0。 :(
I'm using .Net 3.5, not 4.0. :(
推荐答案
我创建了下面的类来做到这一点:
I created the following class to do this:
///<summary>Ensures that a block of code is only executed once at a time.</summary>
class Valve
{
int isEntered; //0 means false; 1 true
///<summary>Tries to enter the valve.</summary>
///<returns>True if no other thread is in the valve; false if the valve has already been entered.</returns>
public bool TryEnter()
{
if (Interlocked.CompareExchange(ref isEntered, 1, 0) == 0)
return true;
return false;
}
///<summary>Allows the valve to be entered again.</summary>
public void Exit()
{
Debug.Assert(isEntered == 1);
isEntered = 0;
}
}
我用这样的:
I use it like this:
readonly Valve valve = new Valve();
public void BeginInvoke(Action method)
{
pendingActions.Enqueue(method);
if (valve.TryEnter())
uiContext.Post(ProcessQueue, null);
}
private void ProcessQueue(object unused)
{
//This runs on the UI thread.
Action current;
while (pendingActions.TryDequeue(out current))
current();
valve.Exit();
}
时的这种模式是否安全?
有没有更好的方式来做到这一点?
是否有该类的更正确的名字?
Is this pattern safe?
Is there a better way to do this?
Is there a more correct name for the class?
这篇关于我如何才能确保只有一个线程会做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文