gpt4 book ai didi

c# - Interlocked.Exchange 有多安全?

转载 作者:行者123 更新时间:2023-11-30 17:50:07 29 4
gpt4 key购买 nike

作为一个线程菜鸟,我正在尝试找到一种不锁定对象的方法,允许我将线程池任务排入队列,这样它的最大并行度 = 1。

这段代码会按照我的想法行事吗?

private int status;
private const int Idle = 0;
private const int Busy = 1;

private void Schedule()
{
// only schedule if we idle
// we become busy and get the old value to compare with
// in an atomic way (?)
if (Interlocked.Exchange(ref status, Busy) == Idle)
{
ThreadPool.QueueUserWorkItem(Run);
}
}

也就是说,如果状态为 Idle,则以线程安全的方式将 Run 方法加入队列。它在我的测试中似乎工作正常,但由于这不是我的领域,我不确定。

最佳答案

是的,这会做你想做的。当实际上状态为 Busy 时,它永远不会允许您获得 Idle 的返回值,并且它会在同一操作中将状态设置为 Busy,而不会发生冲突。到目前为止一切顺利。

但是,如果您使用的是 ConcurrentQueue<T>后来,你为什么要这样做?为什么要用一个 ThreadPool 来排队 Run 一遍又一遍,而不是让一个线程不断地使用 TryDequeue 从并发队列中取数据?

其实有一个producer-consumer collection就是专门为此设计的,BlockingCollection<T> .您的消费者线程只会调用 Take (必要时使用取消标记 - 可能是个好主意)并且要么返回一个值,如 ConcurrentQueue<T>; 如果没有可用的值,则阻塞线程直到有东西可取。当某个其他线程将一个项目添加到集合中时,它将通知尽可能多的消费者,因为它有数据(在您的情况下,不需要任何复杂的东西,因为您只有一个消费者)。

这意味着您只需处理启动和停止单个线程,这将运行一个“无限”循环,它将调用 col.Take ,而生产者调用col.Add .

当然,这假定您有可用的 .NET 4.0+,但话又说回来,您可能会这样做,因为您正在使用 ConcurrentQueue<T> .

关于c# - Interlocked.Exchange 有多安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20994833/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com