pthread_cond_wait从不解锁 - 线程池

时间:2011-02-14 07:37:03

标签: linux multithreading pthreads signals

我正在尝试实现一种线程池,我将线程保存在FIFO中并处理一堆图像。不幸的是,由于某些原因,即使已经发出信号,我的cond_wait并不总是被唤醒。

        // Initialize the thread pool
        for(i=0;i<numThreads;i++)
        {

            pthread_t *tmpthread = (pthread_t *) malloc(sizeof(pthread_t));

            struct Node* newNode;
            newNode=(struct Node *) malloc(sizeof(struct Node));
            newNode->Thread = tmpthread;
            newNode->Id = i;
            newNode->threadParams = 0;
            pthread_cond_init(&(newNode->cond),NULL);
            pthread_mutex_init(&(newNode->mutx),NULL);

            pthread_create( tmpthread, NULL, someprocess, (void*) newNode);
            push_back(newNode, &threadPool);

        }



    for() //stuff here
    {
    //...stuff
        pthread_mutex_lock(&queueMutex);        
            struct Node *tmpNode = pop_front(&threadPool);
        pthread_mutex_unlock(&queueMutex);  

        if(tmpNode != 0)
        {
            pthread_mutex_lock(&(tmpNode->mutx));
                pthread_cond_signal(&(tmpNode->cond)); // Not starting mutex sometimes? 
            pthread_mutex_unlock(&(tmpNode->mutx));     
        }
    //...stuff
    }

 destroy_threads=1;
 //loop through and signal all the threads again so they can exit. 
 //pthread_join here


}

    void *someprocess(void* threadarg)
    {
        do
        {
    //...stuff
            pthread_mutex_lock(&(threadNode->mutx));
                pthread_cond_wait(&(threadNode->cond), &(threadNode->mutx));
                // Doesn't always seem to resume here after signalled.
            pthread_mutex_unlock(&(threadNode->mutx));
        } while(!destroy_threads);

        pthread_exit(NULL);
    }

我错过了什么吗?它的工作时间大约是一半,所以我认为我在某个地方有种族,但我能想到的唯一一件事就是我搞砸了互斥体?我读过一些关于在锁定之前不发信号的事情,但我真的不明白发生了什么。

有什么建议吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

首先,您的示例显示您将queueMutex锁定在pop_front的调用周围,而不是push_back。通常你需要锁定两者,除非你能保证在所有的弹出之前发生所有的推动。

其次,您对pthread_cond_wait的调用似乎没有关联的谓词。条件变量的典型用法是:

pthread_mutex_lock(&mtx);
while(!ready)
{
    pthread_cond_wait(&cond,&mtx);
}
do_stuff();
pthread_mutex_unlock(&mtx);

在此示例中,ready是由另一个线程设置的变量,而该线程在mtx上持有锁。

如果在调用pthread_cond_waitpthread_cond_signal中未阻止等待线程,则将忽略该信号。关联的ready变量允许您处理这种情况,并且还允许您处理所谓的虚假唤醒,其中pthread_cond_wait的调用返回而没有相应的调用来自另一个帖子的pthread_cond_signal

答案 1 :(得分:-1)

我不确定,但我认为您在调用pthread_cond_signal(&amp;(tmpNode-&gt; cond))之前不必(必须)锁定线程池中的互斥锁;否则,被唤醒的线程将无法锁定互斥锁作为pthread_cond_wait(&amp;(threadNode-&gt; cond),&amp;(threadNode-&gt; mutx))的一部分;操作