开发者

pthread_cond_wait never unblocking - thread pools

开发者 https://www.devze.com 2023-02-10 13:18 出处:网络
I\'m trying to implement a sort of thread pool whereby I keep threads in a FIFO and process a bunch of images. Un开发者_Go百科fortunately, for some reason my cond_wait doesn\'t always wake even though

I'm trying to implement a sort of thread pool whereby I keep threads in a FIFO and process a bunch of images. Un开发者_Go百科fortunately, for some reason my cond_wait doesn't always wake even though it's been signaled.

        // 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);
    }

Am I missing something? It works about half of the time, so I would assume that I have a race somewhere, but the only thing I can think of is that I'm screwing up the mutexes? I read something about not signalling before locking or something, but I don't really understand what's going on.

Any suggestions?

Thanks!


Firstly, your example shows you locking the queueMutex around the call to pop_front, but not round push_back. Typically you would need to lock round both, unless you can guarantee that all the pushes happen-before all the pops.

Secondly, your call to pthread_cond_wait doesn't seem to have an associated predicate. Typical usage of condition variables is:

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

In this example, ready is some variable that is set by another thread whilst that thread holds a lock on mtx.

If the waiting thread is not blocked in the pthread_cond_wait when pthread_cond_signal is called then the signal will be ignored. The associated ready variable allows you to handle this scenario, and also allows you to handle so-called spurious wake-ups where the call to pthread_cond_wait returns without a corresponding call to pthread_cond_signal from another thread.


I'm not sure, but I think you don't have to (you must not) lock the mutex in the thread pool before calling pthread_cond_signal(&(tmpNode->cond)); , otherwise, the thread which is woken up won't be able to lock the mutex as part of pthread_cond_wait(&(threadNode->cond), &(threadNode->mutx)); operation.

0

精彩评论

暂无评论...
验证码 换一张
取 消