【问题标题】:Global array storing counters updated by each thread; main thread to read counters on demand?全局数组存储每个线程更新的计数器;主线程按需读取计数器?
【发布时间】:2017-02-25 20:27:41
【问题描述】:

场景如下:一个主线程产生最多 N 个工作线程,每个工作线程都会更新一个计数器(比如它们正在计算每个线程处理的请求数)。

主线程也需要在 API 请求时读取总计数器。

我想这样设计它:

1) 计数器的全局哈希图/数组/链表。

2) 每个工作线程都使用线程 ID 作为键来访问这个全局结构,因此不需要互斥锁来保护一个工作线程免受另一个工作线程的影响。

3) 然而,困难的部分是:我在网上找不到任何例子来处理这个问题:我希望主线程能够按需读取和汇总所有计数器值,例如服务 API 请求。我需要一个互斥锁,对吧?

因此,实际上,我需要一个每个工作线程的互斥锁,它会在更新全局数组之前锁定互斥锁——假设每个工作线程只与主线程竞争,只有当主线程为API 请求。

主线程:当它接收到 API 请求时,它必须一个一个地锁定每个工作线程特定的互斥锁,读取该线程的计数器以获得总计数。

我是否过于复杂了?我不喜欢在这个设计中要求每个工作线程的互斥锁。

感谢您的任何意见。

【问题讨论】:

  • 你会需要一个互斥体,是的。
  • 你并没有把任何事情都复杂化。正确的多线程设计很复杂。

标签: java python c++ multithreading pthreads


【解决方案1】:

您的设计听起来是正确的方法。不要将它们视为每个线程的互斥体:将它们视为每个计数器的互斥体(数组的每个元素都应该是互斥体/计数器对)。

在主线程中,可能不需要锁定所有互斥体然后读取所有计数器:如果值类似于您的示例(每个线程处理的请求数)一起读取所有计数器并没有比按顺序读取它们给出“更正确”的答案。

或者,如果您的语言/环境提供原子变量,您可以将原子变量用于计数器而不是锁。

【讨论】:

    【解决方案2】:

    只需使用std::atomic<int> 来保持运行计数。当任何线程更新其计数器时,它也会更新运行计数。当主线程需要计数时,它会读取运行计数。结果可能在任何给定时刻都小于实际总数,但只要事情稳定下来,总数就会正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 2015-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      相关资源
      最近更新 更多