pthread_cond_wait太慢了,这是更好的方法吗?

时间:2014-07-07 00:58:12

标签: c multithreading threadpool

我使用了线程池,主线程将任务连续添加到队列中,并抛出一个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);
}

0 个答案:

没有答案