我想知道如何在可执行线程中做到线程安全,让我用例子来解释一下:
假设我想要一个接一个连续执行的命令管道,但是在我的线程中我不能等待它们。线程通常处于休眠状态,如果某个命令进入队列,则会被唤醒,然后它将执行队列中的所有命令,并再次进入休眠模式,直到新命令进入队列。类似于:
public void Enqueue(ICommand command)
{
this.queue.Enqueue(command);
this.synchroHandler.Set();
}
private void Pipeline()
{
while (true)
{
this.synchroHandler.WaitOne();
while (this.queue.Count > 0)
{
ICommand command = this.queue.Dequeue();
command.Execute();
}
// what if command will be enqueued between previous command - HERE
// ... and this command HERE
this.synchroHandler.Reset();
}
}
public void Main()
{
this.queue = new ThreadSafeQueue<ICommand>();
this.computionHandler = new ManualResetEvent(false);
Thread thread = new Thread(new ThreadStart(this.Pipeline));
thread.Start();
// start adding commands to pipeline
this.Enqueue(command1);
this.Enqueue(command2);
...
}假设我的queue实现是线程安全的,所以this.queue.Count、this.queue.Enqueue和this.queue.Dequeue使用相同的锁。如果在"}“和this.synchroHandler.Reset()之间调用public Enqueue(),线程将会休眠,即使它在队列中有一个条目(this.synchroHandler.Set()将在this.synchroHandler.Reset()之前被调用)。你知道如何让这个模式是线程安全的吗?
发布于 2010-11-09 02:35:06
查看System.Collections.Concurrent名称空间中的线程安全生产者-消费者BlockingCollection。
发布于 2010-11-09 05:34:49
应该在WaitOne()之后立即调用this.synchroHandler.Reset()。
因此,如果队列在重置之前被调用,您将进入while循环,如果它在您检查queue.Count之后被调用,那么下次您调用WaitOne()时,它将立即返回并进入while循环。
发布于 2010-11-09 06:04:23
你能把它改成旋转吗?因此,每隔10ms,线程就会唤醒并检查队列是否有项,否则将再次进入休眠状态。
while (true)
{
while (this.queue.Count > 0)
{
ICommand command = this.queue.Dequeue();
command.Execute();
}
Thread.Sleep(10);
}https://stackoverflow.com/questions/4126739
复制相似问题