luyi0619
luyi0619

Reputation: 313

why does pthread_cond_signal cause deadlock

I am new to conditional variables and get deadlock if not using pthread_cond_broadcast().

#include <iostream>
#include <pthread.h>

pthread_mutex_t m_mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;

bool ready = false;

void* print_id (void *ptr )
{
    pthread_mutex_lock(&m_mut);
    while (!ready) pthread_cond_wait(&cv, &m_mut);
    int id = *((int*) ptr);
    std::cout << "thread " << id  << '\n';
    pthread_mutex_unlock(&m_mut);
    pthread_exit(0);
    return NULL;
}

condition is changed here!

void go() {
    pthread_mutex_lock(&m_mut);
    ready = true;
    pthread_mutex_unlock(&m_mut);
    pthread_cond_signal(&cv);
}

It can work if I change the last line of go() to pthread_cond_broadcast(&cv);

int main ()
{
    pthread_t threads[10];

    // spawn 10 threads:
    for (int i=0; i<10; i++)
        pthread_create(&threads[i], NULL, print_id, (void *) new int(i));

    go();

    for (int i=0; i<10; i++) pthread_join(threads[i], NULL);

    pthread_mutex_destroy(&m_mut);
    pthread_cond_destroy(&cv);

    return 0;
}

The expected answer (arbitrary order) is

thread 0

....

thread 9

However, on my machine (ubuntu), it prints nothing. Could anyone tell me the reason? Thanks.

Upvotes: 4

Views: 931

Answers (1)

abligh
abligh

Reputation: 25189

From the manual page (with my emphasis):

pthread_cond_signal restarts one of the threads that are waiting on the condition variable cond. If no threads are waiting on cond, nothing happens. If several threads are waiting on cond, exactly one is restarted, but it is not specified which.

pthread_cond_broadcast restarts all the threads that are waiting on the condition variable cond. Nothing happens if no threads are waiting on cond.

Each of your ten threads is waiting on the same condition. You only call go() once - that's from main(). This calls pthread_cond_signal, which will only signal one of the threads (an arbitrary one). All the others will still be waiting, and hence the pthread_join hangs as they won't terminate. When you switch it to pthread_cond_broadcast, all of the threads are triggered.

Upvotes: 2

Related Questions