Home > Blockchain >  Unlocking the condition variable mutex twice?
Unlocking the condition variable mutex twice?

Time:06-01

I'm looking at the following snippets:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cvar;
char buf[25];
void*thread_f(void *);

int main(){

    pthread_t thr; 
    pthread_cond_init(&cvar,NULL);
    pthread_mutex_lock(&mtx);
    pthread_create(&thr,NULL,thread_f,NULL);
    pthread_cond_wait(&cvar,&mtx);
    pthread_mutex_unlock(&mtx);
    ...join and destroy thread...
}

and thread_f:

void* thread_f(void* argp){

    pthread_mutex_lock(&mtx);
    strcpy(buf,"test");
    pthread_cond_signal(&cvar);
    pthread_mutex_unlock(&mtx); //why?
    pthread_exit(NULL);
}

My understanding of the above code is, that main grabs the lock, creates the thread and runs thread_f which blocks. Then, main signals the wait on the condition variable cvar and unlocks the mutex. Then, thread_f unblocks, strcpys and signals cvar to wake up. Then, both main and thread_f unlock the mutex.

Is this the actual behaviour, or am I missing something somewhere? If it's the actual behaviour, isn't unlocking the already unlocked mutex UB, therefore should one of he mutex unlocks in the end be removed?

Thanks.

CodePudding user response:

What this code is doing is valid.

When the thread calls pthread_cond_signal it doesn't immediately cause the main thread to grab the mutex, but wakes up the main thread so it can attempt to lock it. Then once the thread releases the mutex, the main thread is able to lock it and return from pthread_cond_wait.

CodePudding user response:

The pthread_cond_wait() in the main thread unlocks the mutex and waits for the condition to be signalled — and relocks the mutex before returning.

The child thread is able to lock the mutex, manipulate the buffer, signal the condition and then unlock the mutex, letting the main thread reacquire the lock.

Consequently, the code is well-behaved — give or take the need to worry about 'spurious wakeups' in more general situations with multiple child threads. I don't think you can get a spurious wakeup here.

  • Related