这里是场景:一个主线程产生最多N个工作线程,每个线程都会更新一个计数器(比如他们正在计算每个线程处理的请求数)。
总计数器也需要由主线程在API请求中读取。
我正在考虑设计它:
1)全局hashmap / array / linked-list of counters。
2)每个工作线程使用线程ID作为键访问此全局结构,因此不需要互斥锁来保护一个工作线程与另一个工作线程。
3)然而,这是一个棘手的部分:没有我在网上可以找到的例子处理这个:我希望主线程能够按需读取和总结所有计数器值,比如提供API请求。我需要一个互斥锁,对吧?
所以,实际上,我需要一个per-worker-thread互斥锁,它会在更新全局数组之前锁定互斥锁 - 假设每个工作线程只与主线程争用,则互斥锁只有在主线程服务时才会失败API请求。
主线程:当它收到API请求时,它必须逐个锁定每个特定于工作线程的互斥锁,读取该线程的计数器以获得总计数。
我是否过于复杂?我不喜欢在这个设计中要求每个工人的线程互斥。
感谢任何投入。
答案 0 :(得分:0)
只需使用std::atomic<int>
即可保持运行计数。当任何线程更新其计数器时,它也会更新运行计数。当主线程需要计数时,它会读取运行计数。结果可能会低于任何特定时刻的实际总数,但每当事情稳定下来时,总数就会合适。
答案 1 :(得分:0)
您的设计听起来像是正确的方法。不要将它们视为每线程互斥体:将它们视为每个计数器互斥体(数组的每个元素应该是互斥/计数器对)。
在主线程中,可能不需要锁定所有互斥锁然后读取所有计数器:您可能能够按顺序对每个计数器执行锁定/读取/解锁,如果值类似于你的例子(每个线程处理的请求数)在一起读取所有计数器并不能提供“更正确”的答案,而不是按顺序读取它们。
或者,如果您的语言/环境提供了,则可以使用原子变量代替锁定。