我必须编写一个使用CURL在Web上发布信息的C应用程序。 应用程序最多只能并行运行N个(比方说10个)请求。 我如何等待任何线程完成,而不是使用pthread_join()
特定线程。
我读了关于pthread_cond_wait,但大多数例子是如何控制线程(主)唤醒工作线程。 我只需要相反 – 工作线程必须能够在退出之前发信号/唤醒父线程。
更新:其实我需要一种方法让经理线程睡眠,当一个工作线程完成它的工作,它应该唤醒经理线程给它另一份工作。 如果线程将结束并且将为该作业创build新线程或线程池将被使用,则无关紧要。 Threre仍然需要成为向经理表明工作已完成的一种方式。
我希望我不会得到这个build议 :
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); } }
条件变量是你所追求的。 它们可以很容易地用来从工作者线程发信号通知管理器线程,反之亦然。
最后,你的strawman例子与使用条件变量可以做的很相似:
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);
不是按需创建/销毁线程,而是在启动时创建一个包含10个工作线程的池,并让主程序为其提供作业。
在启动时,您将创建一个由10名工作人员组成的阵列。 这些可能看起来像
typedef struct worker { pthread_t thread; pthread_cond_t cond; pthread_mutex_t mutex; struct job* job; int quit; } worker;
经理通过设置他们的job
人员然后发信号通知job
人员轮流将工作分配给每个线程。
每个工人都会循环,直到quit
不为零,等待其信号状态。 在每个信号之后,它会在报告结果之前读取/处理其job
,然后再次等待其状态。
编辑:你不喜欢线程池。 你可以尝试给每个线程一个唯一的ID; 存储管理器中每个线程的id和其他属性之间的映射。 当每个线程完成时,将它的id添加到管理器拥有的列表中,然后在管理器中发出一个条件。 每次管理员醒来,它可以从列表中拉出头,查找适当的线程,回读其作业结果,然后加入线程。 请注意,这里的管理器列表将被多个线程访问,所以读/写需要被互斥体保护。
编辑2:你想知道更多的条件,没有找到你发现有用的例子。 我不确定这会更好,但是这是我写的一些代码 。 OsSemaphore*
函数将条件包装成简单的等待/信号API。
你想要一个条件变量,你一直在看的相同的功能,但只是转过身来。 你正在等待的条件是“一个工作者的线程已经完成了一些工作”。
主线程确实:
每个工作线程,当它完成工作时: