【问题标题】:Seeking help with a MT design pattern寻求 MT 设计模式的帮助
【发布时间】:2010-03-31 05:00:12
【问题描述】:

我有一个包含 1000 个工作项的队列和一台 n-proc 机器(假设 n = 4). 主线程一次产生 n (=4) 个工作线程 ( 25 个外部 迭代)并在处理之前等待所有线程完成 接下来的 n (=4) 个项目,直到整个队列被处理完

for(i= 0 to queue.Length / numprocs) 
        for(j= 0 to numprocs) 
        { 


                CreateThread(WorkerThread,WorkItem) 


        } 
        WaitForMultipleObjects(threadHandle[]) 

每个(工作者)线程所做的工作不是同质的。因此在 如果线程 1 花费 1000 秒做工作,则 1 批(n 个),其余的 3 线程只有 1 秒,以上设计效率低下,因为 1 秒后 其他 3 个处理器处于空闲状态。此外没有池 - 1000 正在创建不同的线程

如何使用 NT 线程池(我不够熟悉 - 因此 冗长的问题)和 QueueUserWorkitem 来实现上述目标。这 以下约束应该成立

  1. 主线程要求所有工作项在处理之前 它可以继续进行。所以我认为上面的构造类似waitall 是必需的
  2. 我想创建与处理器一样多的线程(即不是 1000 个线程 一次)
  3. 另外我不想创建 1000 个不同的事件,传递给工作人员 线程,并使用 QueueUserWorkitem API 等待所有事件或 否则
  4. 现有代码是 C++。首选 C++,因为我不懂 c#

我怀疑以上是一种非常常见的模式,并且正在寻找 你们的意见。

【问题讨论】:

  • “我也不想创建 1000 个不同的事件,传递给工作线程,并使用 QueueUserWorkitem API 或其他方式等待所有事件”--- 为什么不呢?对我来说似乎是一种合理的方法。

标签: multithreading


【解决方案1】:

我不是 C++ 程序员,所以我给你一些中途的伪代码

tcount = 0
maxproc = 4
while queue_item = queue.get_next() # depends on implementation of queue
                                    # may well be: 
                                    # for i=0; i<queue.length; i++
    while tcount == maxproc
        wait 0.1 seconds # or some other interval that isn't as cpu intensive 
                         # as continously running the loop
    tcount += 1 # must be atomic (reading the value and writing the new 
                # one must happen consecutively without interruption from 
                # other threads). I think ++tcount would handle that in cpp.
    new thread(worker, queue_item)

function worker(item)
    # ...do stuff with item here...
    tcount -= 1 # must be atomic

【讨论】:

  • 实际上,它几乎与您能得到的一样有效。它将它限制为 4 个工作线程,并且一旦任何线程可用,它就会在给定的等待时间内执行下一项。唯一的问题是工作线程必须处理一个外部变量,这可能会破坏一些“好的约定”,但只需对其进行注释以使其清楚,这是一个非常有效的“hack”。