pthreads:重入/可重用线程的线程池同步方法?

时间:2013-01-22 18:27:50

标签: multithreading synchronization pthreads threadpool

这是我在这里的第一篇文章,感谢您提前的宽容。

我有一个带有作业队列>>的线程池线程数。

流程:

  1. 初始线程池(M个线程数)
  2. 将N个任务放入队列(N可以是>> M)
  3. 线程开始执行任务;完成当前任务线程后自动执行下一个可用任务。
  4. 同步点 - 必须完成所有任务。
  5. 数据处理(单线程)
  6. 根据已处理的数据生成任务或退出
  7. 转到2
  8. 问题是同步点。我已经使用counter和mutex实现了简单的信号量:在第2步计数器初始化之前,要加载的任务数量以及每个任务完成时计数器递减。如果counter == 0,那么我从工作线程发送pthread_cond_signal,并且在步骤4中pthread_cond_wait捕获它。

    我觉得这不是最有效的方法(我不喜欢锁定/解锁每个线程中的计数器减量,这是一个很大的开销,特别是如果任务有效负载很小),但是无法了解如何改进。 我知道障碍,但我不能在线程中使用pthread_barrier_wait,因为它们必须在同步事件发生之前多次重复使用。

    pthread_spin_lock关于队列中的任务数量?即使队列为空,也不意味着线程没有运行 - 它们可能在最后的M个任务中。我无法加入线程,因为它们将在下一个周期中重用。

    我很感激任何意见/建议。 谢谢。

1 个答案:

答案 0 :(得分:0)

好吧,你可以通过在计数器上使用原子递减指令而不是内核锁来优化它一点 - 将计数器递减到零的线程然后可以调用一些'OnComplete(something)'方法/函数也许,这可能是原始线索的信号(就像你现在所做的那样)。

无论你如何设计你的队列和障碍/集合点,这都是不值得的。无论如何,当您的原始线程进入等待时以及在任务完成后再次运行时,通常会有两个上下文更改,如果池不忙并且队列中的池线程被阻塞,则会更多。在完成计数上旋转将从你的CPU池中吸取一个核心 - 不太可能有用,(特别是如果你设计你的池并行运行多组任务 - 将会有多个原始线程在旋转)

不要断开CPU平凡任务。如果要完成大量的CPU工作,或者任务执行阻塞操作,并且线程数多于核心数,那很好。