【问题标题】:thread-safe inside thread worker线程工作者内部的线程安全
【发布时间】:2011-05-06 19:39:37
【问题描述】:

我想知道如何在执行线程内部做线程安全,让我通过例子来解释一下:

可以说我想要一个命令的管道,这些命令应该一个一个地连续执行,但是在我的线程中我等不及了。线程通常处于休眠状态,如果某个命令入队则被唤醒,然后它执行队列中的所有命令并再次进入休眠模式,直到新命令入队。类似:


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);
    ...
}

假设我的队列实现是线程安全的,所以 this.queue.Count、this.queue.Enqueue 和 this.queue.Dequeue 使用相同的锁。示例中显示的 Ss 如果将在“}”和 this.synchroHandler.Reset() 之间调用 public Enqueue();即使队列中有一个项目,线程也会最终进入休眠状态(this.synchroHandler.Set() 将在 this.synchroHandler.Reset() 之前被调用)。知道如何使这个模式成为线程安全的吗?

【问题讨论】:

    标签: c# synchronization thread-safety


    【解决方案1】:

    查看BlockingCollection&lt;T&gt;,System.Collections.Concurrent 命名空间中的线程安全生产者-消费者。

    【讨论】:

      【解决方案2】:

      你应该在 WaitOne() 之后调用 this.synchroHandler.Reset()。

      因此,如果 Queue 在 Reset 之前被调用,你将进入 while 循环,如果它在你检查 queue.Count 之后被调用,下次你调用 WaitOne() 时,它会立即返回并进入 while 循环。

      【讨论】:

        【解决方案3】:

        你能把它改成旋转吗?因此,每 10 毫秒,线程唤醒并检查队列是否有项目,否则再次进入睡眠状态。

        while (true)
            {
                while (this.queue.Count > 0)
                {
                    ICommand command = this.queue.Dequeue();
                    command.Execute();
                }
                Thread.Sleep(10);
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-29
          • 2020-02-15
          • 1970-01-01
          • 2021-09-10
          • 2013-06-05
          • 2022-11-21
          • 1970-01-01
          相关资源
          最近更新 更多