我必须编写一个使用CURL在Web上发布信息的C应用程序。应用程序最多必须并行运行N(比如说10个)请求。我如何等待任何线程完成,而不是等待使用pthread_join()
的特定线程。
我读到了pthread_cond_wait,但大多数示例都是控制线程(main)如何唤醒工作线程。我需要恰恰相反 - 工作线程必须能够在退出之前发出信号/唤醒父线程。
更新:实际上我需要一种让管理器线程休眠的方法,当工作线程完成它的工作时,它应该唤醒管理器线程以给它另一份工作。如果线程将结束并且将为作业创建新线程,则将使用线程池无关紧要。 Threre仍然需要一种向经理发出工作结束信号的方式。
我希望我不会得到这个建议:
while(asleep){
for(i = 0; i< threadCount; i++){
pthread_mutex_lock(mutex);
if(threads[i] == IDLE_STATE)
startNewJob();
pthread_mutex_unlock(mutex);
usleep(100*1000);
}
}
答案 0 :(得分:4)
而不是创建/销毁点播线程,它&#39;会更容易在启动时创建的10个工作线程池,让你的主程序饲料工作给他们。
启动时,您将创建一个包含10名工作人员的阵列。这些可能看起来像
typedef struct worker
{
pthread_t thread;
pthread_cond_t cond;
pthread_mutex_t mutex;
struct job* job;
int quit;
} worker;
管理员会通过设置job
成员然后向工作人员发出信号,依次将作业委派给每个线程。
每个工作人员都会循环,直到quit
为非零,等待其状态发出信号。在每个信号发出之后,它会在报告结果之前读取/处理其job
,然后再次等待其状态。
编辑:您并不热衷于线程池。你可以尝试给每个线程一个唯一的id;在管理器中的每个线程的id和其他属性之间存储一些映射。当每个线程完成时,让它将其id添加到管理器拥有的列表中,然后在管理器中发出一个条件。每次管理器唤醒时,它都可以从列表中拉出头部,查找相应的线程,读回其作业结果然后加入线程。请注意,此处的管理器列表将由多个线程访问,因此读/写需要由互斥锁保护。
编辑2:您想了解更多有关条件的信息,并且找不到您认为有用的示例。我不确定这会更好,但这里some code I've written。 OsSemaphore*
函数将条件包装到一个简单的Wait / Signal API中。
答案 1 :(得分:1)
您需要一个条件变量,与您一直在查看的相同功能,但只是转身。你正在等待的条件是“工人线程完成了一些工作”。
主线程确实:
每个工作线程在完成工作时都会:
答案 2 :(得分:1)
条件变量就是你所追求的。它们可以很容易地用来从工作线程发出管理器线程的信号,反之亦然。
最后你的稻草人示例实际上与你使用条件变量所做的非常相似:
pthread_mutex_lock(&mutex);
while (!finished) {
for(i = 0; i < threadCount; i++) {
if(threads[i] == IDLE_STATE)
startNewJob(i);
}
/* Not finished, and no idle threads, so wait */
if (!finished)
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
线程完成后,它只会执行:
pthread_mutex_lock(&mutex);
threads[self] = IDLE_STATE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);