从多个线程更新单个值

Posted

技术标签:

【中文标题】从多个线程更新单个值【英文标题】:Updating a single value from multiple threads 【发布时间】:2013-07-15 07:38:23 【问题描述】:

我有一个计数器 - 我们就叫它:ItemsRemaining。

我将有一个动态数量的线程,但是对于这个例子,假设我有 10 个线程.....

每个线程都会包含一个循环,循环中的每次迭代都会完成一个工作单元,然后应该更新 GUI 线程上的 ItemsRemaining 变量。这可能是一个私有 int,甚至可能是一个控制值。

如何从多个线程调用中准确更新此 ItemsRemaining?同时不会因锁定而对性能造成太大影响?

【问题讨论】:

您能否创建一个静态类来控制剩余的单位数量并处理任何传入的更改。然后每个线程可以只引发一个事件,然后控制类可以处理所有传入的事件。 【参考方案1】:

您应该检查Interlocked 类中的方法。

【讨论】:

这就是我想写的,但后来我注意到了GUI 部分。 使用 Interlocked 更新 UI 使用的变量很好。如果还需要运行代码以更新 UI 本身,则可以使用 Interlocked 更新变量,并使用 Form.Invoke 更新 UI。【参考方案2】:

我相信锁定是同步两个线程的最快方式。如果你已经在使用它,你应该很好。

【讨论】:

【参考方案3】:

您可以使用简单的锁或Interlocked.Decrement。如果您的任何线程值得一开始就创建,我认为锁定任何内容都不会影响性能。

【讨论】:

与锁相关,不是锁本身会导致性能下降,而是锁竞争,因为它可能会降低应用程序实现的并行度。如果可以用Interlocked代替锁,应该是首选。【参考方案4】:

如果您要在变量的每个增量上更新 UI,则使用线程中的 Control.Invoke (Winforms) 或 Dispatcher.Invoke (WPF) 调用更新 UI 的方法 - 并递增 int 变量在您更新 UI 之前,该方法 本身。这样就不需要锁定,因为对变量的修改会通过 UI 线程自动同步。

如果您不想让工作线程等待 UI 更新完成,您也可以使用 BeginInvoke 变体。

【讨论】:

以上是关于从多个线程更新单个值的主要内容,如果未能解决你的问题,请参考以下文章

在多个 qt 线程中使用单个 QSqlDatabase 连接

来自多个线程的共享锁会使寻找独占锁的单个线程饿死

C++ 线程

拥有多个线程池与单个线程池相比有啥好处?

与多个线程池相比,单个线程池的设计是不是更好

多个生产者,单个消费者