这是我第一次尝试多线程,并且我正在尝试在c中创建线程池,作为分配的一部分。因此,只允许我使用系统调用和pthread,但是我遇到的问题不需要在分配中解决-这只是我要学习的,但我仍然只想使用这些资源。 /> 我为我的线程池创建了一个结构,并在每个创建的线程上运行了一个函数-等待任务进入队列。 我想确保所有线程在完成线程池创建功能之前都在等待特定的wait_condition-(即:正在等待空队列状态)。 如果我不能确保所有线程都在等待任务进入队列,则以下代码片段将创建一个池并在将任何任务出队之前销毁它,因为在线程到达cond_wait之前将stop变量设置为true:
void test()
{
int i;
ThreadPool* tp = tpCreate(5);
for(i=0; i<5; ++i)
{
tpInsertTask(tp,foo(),args);
}
//NO_WAIT flag is raised so the pool wont finish
//remaining tasks in queue before stopping
tpDestroy(tp,NO_WAIT);
}
这些是我创建的结构:
typedef struct thread_pool
{
int poolSize;
volatile int stop ;
volatile int running;
OSQueue* queue ;
pthread_t* threadID;
pthread_mutex_t shared_lock;
pthread_cond_t emptyQ ;
pthread_cond_t poolStarted;
}ThreadPool;
//this is used to run Tasks in queue
struct TaskHandler
Bellow是线程池的简化创建函数: (safe_lock只是一个锁定池中唯一互斥量并检查mutex_lock(&m)返回值的函数。)
ThreadPool* tpCreate(int numOfThreads) {
ThreadPool *tp = (ThreadPool *) malloc(sizeof(ThreadPool));
/** ... **/
//create pool
for (i = 0; i < numOfThreads; i++) {
err = pthread_create(&tp->threadID[i], NULL, start, tp);
/** error check ..**/
}
//wait for the last function to reach waiting status
safe_lock(tp);
do{
//wait until the last thread has reached waiting status
pthread_cond_wait(&tp->poolStarted,&tp->shared_lock);
//set thread-pool status as running
tp->running = TRUE;
}while(!tp->running);
safe_unlock(tp);
return tp;
}
以下代码显示了我已经尝试过的内容, 这是在池中创建的每个线程上运行的启动函数:
void* start(void* args) {
ThreadPool *tp = (ThreadPool *) args;
if (!tp) {
return NULL;
}
//i did allso try to replace condition to while(!stop)
while (TRUE) {
TaskHandler *taskHandler = NULL;
safe_lock(tp);
if (shouldStop(tp)) {
safe_unlock(tp);
return NULL;
} else if (osIsQueueEmpty(tp->queue)) {
//if current thread is the last to be created , signal to create function
if (!tp->running &&
tp->threadID[tp->poolSize - 1] == pthread_self() ) {
pthread_cond_signal(&tp->poolStarted);
}else{
//signals when a task pushed to queue
int err = pthread_cond_wait(&tp->emptyQ, &tp->shared_lock);
/** error check .. **/
}
}
taskHandler = (TaskHandler *) osDequeue(tp->queue);
safe_unlock(tp);
/** if task!=null run it **/
}
}
停止功能:
void stopThreads(ThreadPool* tp){
//sanity check
if(!tp ){
return;
}
safe_lock(tp);
tp->stop = TRUE;
pthread_cond_broadcast(&tp->emptyQ);
safe_unlock(tp);
}
我的逻辑说,在创建最后一个线程时,它将一直向主线程发送信号,直到将运行条件设置为true为止;
因此它停止发信号,可以安静地等待任务入队。
我还试图计算达到cond_wait的线程数,但没有成功,因为据我所知,cond_wait并不容纳信号队列,因此我无法统计有多少线程确实达到了该条件,有时还没有信号当主线程未再次达到cond_wait时发送。
因此,这是我经过多次尝试才能获得的最好成绩,但是该池在停止之前仍运行可变数量的功能。
当然,我想避免使用睡眠或while循环进行任何繁忙的等待。
我将不胜感激任何帮助,
谢谢。