等待几个线程中的一个完成?

时间:2010-11-24 07:40:25

标签: c pthreads

我正在实现一个线程池。每个线程所需的工作是1-10秒的CPU,所以我很高兴有一个传统的工作线程池,或者我很乐意为每个工作单元生成一个新的线程。没关系。

我想有一些方法让主控制线程知道N个工作线程中的一个何时完成其工作并准备好更多(或者是时候启动另一个)。我看过pthread_join和pthread_cond_wait。似乎没有办法等待N中的一个。所以我想主线程有一个变量,它用来进入睡眠并让工人将其唤醒。如果工人不死,这似乎有效。然而,如果他们死了,那么工人唤醒控制器的时间和死亡时间之间就有一个窗口,我不想处理。

我看过英特尔的TBB,但它看起来比我需要的要复杂得多。

在Microsoft Windows中是否存在PTHREADS中的WaitForMultipleObjects的简单等效项?

3 个答案:

答案 0 :(得分:3)

对于条件变量,这是一个相当简单的用例。

对活动工作项的数量进行整数计数,保护互斥锁。此外,还有两个条件变量,一个用于发信号通知工作在队列中可用的工作线程,另一个用于表示线程已完成的主线程。类似的东西:

main:
    set freethreads to numthreads
    init mutex M, condvars TOMAIN and TOWORKER
    start N worker threads
    while true:
        wait for work item
        claim M
        while freethreads == 0:
            cond-wait TOMAIN, M
        put work item in queue
        decrement freethreads
        cond-signal TOWORKER
        release M

worker:
    init
    while true:
        claim M
        while no work in queue:
            cond-wait TOWORKER, M
        get work to local storage
        release M
        do work
        claim M
        increment freethreads
        cond-signal TOMAIN
        release M

请注意,循环永远运行。实际上,会有信号使它们退出并运行终止/清理代码。

答案 1 :(得分:1)

您是否考虑过使用计数信号量?

答案 2 :(得分:1)

从架构的角度来看,它是线程池的责任。应该存在工作者和池之间的同步。

pthread_mutex_lock()或计数信号量(sem_wait()和sem_post())适用于此类同步。一种方法可以说明如下:

  1. 池init是计数信号量,通过调用:sem_init(p_to_sem_t,0,int n);
  2. n工人通过调用:sem_wait();
  3. 获取信号量
  4. 游泳池通过调用:sem_wait();
  5. 等待工人回来
  6. 池检查信号量计数以查看是否所有工作人员都已停放。
  7. 工作人员在退出时通过调用释放锁:sem_post();