我使用了线程池,主线程将任务连续添加到队列中,并抛出一个pthread_cond_signal,表明队列对于工作线程不是空的。然后工作线程读取队列并抛出一个pthread_cond_signal指示队列未满主线程。当程序运行时,我发现pthread_cond_wait非常慢,如果我删除函数threadpool_add中的pthread_cond_wait,它会快得多,但我怀疑它可能有什么问题,我怎样才能让threadpool_add函数更快?它是我项目的性能瓶颈,以下是代码:
/*
* @function int threadpool_add(threadpool_t *pool, void*(*function)(void *arg), void *arg, char* buf)
* @desc add tasks to the queue
* @param [thread_num] number of thread in pool,
* [queue_max_size] size of the queue for task
*/
int threadpool_add(threadpool_t *pool, void*(*function)(void *arg), void *arg)
{
ulogd_log(ULOGD_NOTICE, "in threadpool_add\n");
if(pool == NULL || function == NULL || arg == NULL)
{
return -1;
}
pthread_mutex_lock(&(pool->lock));
/*
* wait untill queue is not full
*/
while ((pool->queue_size == pool->queue_max_size) && (!pool->shutdown))
{
pthread_cond_wait(&(pool->queue_not_full), &(pool->lock)); // if delete this, it's quicker
}
if (pool->shutdown)
{
pthread_mutex_unlock(&(pool->lock));
return 0;
}
pool->task_queue[pool->queue_rear].function = function;
pool->task_queue[pool->queue_rear].arg = arg;
pool->queue_rear = (pool->queue_rear + 1)%pool->queue_max_size;
pool->queue_size++;
/*
* notify to the threads, there has a task
*/
pthread_cond_signal(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->lock));
ulogd_log(ULOGD_NOTICE, "threadpool_add, tpool:0x%x, shutdown: %d, queue_size:%d, queue_not_empty:0x%x\n", pool, pool->shutdown, pool->queue_size, &(pool->queue_not_empty));
return 0;
}
void *threadpool_thread(void *threadpool)
{
threadpool_t *pool = (threadpool_t *)threadpool;
threadpool_task_t task;
while(1)
{
ulogd_log(ULOGD_NOTICE, "in thread 0x%x, tpool: 0x%x\n", pthread_self(), pool);
/* Lock must be taken to wait on conditional variable */
pthread_mutex_lock(&(pool->lock));
while ((pool->queue_size == 0) && (!pool->shutdown))
{
ulogd_log(ULOGD_NOTICE, "thread 0x%x is waiting, queue_size:%d, queue_not_empty:0x%x\n", pthread_self(), pool->queue_size, &(pool->queue_not_empty));
pthread_cond_wait(&(pool->queue_not_empty), &(pool->lock));
}
if (pool->shutdown)
{
pthread_mutex_unlock(&(pool->lock));
ulogd_log(ULOGD_NOTICE,"thread 0x%x is exiting\n", pthread_self());
pthread_exit(NULL);
}
//get a task from queue
task.function = pool->task_queue[pool->queue_front].function;
task.arg = pool->task_queue[pool->queue_front].arg;
pool->queue_front = (pool->queue_front + 1)%pool->queue_max_size;
pool->queue_size--;
//now queue must be not full
pthread_mutex_unlock(&(pool->lock));
pthread_cond_signal(&(pool->queue_not_full));
// Get to work
ulogd_log(ULOGD_NOTICE, "thread 0x%x start working\n", pthread_self());
(*(task.function))(task.arg);
// task run over
ulogd_log(ULOGD_NOTICE, "thread 0x%x end working\n", pthread_self());
}
pthread_exit(NULL);
return (NULL);
}