首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Interlocked.Exchange有多安全?

Interlocked.Exchange有多安全?
EN

Stack Overflow用户
提问于 2014-01-08 11:49:59
回答 1查看 365关注 0票数 3

作为一个线程程序,我试图找到一种方式w/o锁定对象,它允许我对线程池任务进行排队,使它具有最大程度的并行性= 1。

这段代码能像我想的那样做吗?

代码语言:javascript
复制
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);
    }
}

也就是说,如果状态为Run,则以线程安全的方式对该方法进行排队。这似乎在我的测试中很好,但由于这不是我的领域,我不确定。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-08 12:46:46

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

但是,如果以后使用的是ConcurrentQueue<T>,为什么还要这样做呢?为什么要使用ThreadPool来一次又一次地运行队列,而不是让单个线程使用TryDequeue不断地从并发队列中获取数据?

事实上,有一个生产者-消费者的集合,是专门为此设计的,BlockingCollection<T>。您的使用者线程只需调用Take (如果有必要,可以使用取消令牌--这可能是个好主意),如果返回ConcurrentQueue<T>;中的值,或者如果没有可用的值,则阻塞线程,直到有东西可取为止。当其他线程向集合中添加项时,它会通知尽可能多的使用者(在您的情况下,不需要任何复杂的东西,因为您只有一个使用者)。

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

当然,这假设您有.NET 4.0+可用,但同样,您可能会这样做,因为您正在使用ConcurrentQueue<T>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20994833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档