简体   繁体   中英

What happens when a thread calls pthread_mutex_unlock on an already unlocked mutex

I know this question sounds familiar and it might even be a stupid question but I wasn't able to find the solution to it.

So my question basically is, what happens when a parent_thread calls pthread_mutex_lock(&mutex) then calls pthread_cond_wait(&condition, &mutex) releasing the mutex, and then child_thread calls pthread_mutex_lock(&mutex) followed by pthread_cond_signal(&condition) and then pthread_mutex_unlock(&mutex) . So this would mean that the mutex is unlocked and now if parent_thread attempts to call pthread_mutex_unlock(&mutex) , it should result in undefined behavior, right ?

Example code:

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;

void thr_exit() {
  pthread_mutex_lock(&m);
  done = 1;
  pthread_cond_signal(&c);
  pthread_mutex_unlock(&m);
}

void *child(void *arg) {
  printf("child\n");
  thr_exit();
  return NULL;
} 
void thr_join() {
  pthread_mutex_lock(&m);
  while (done == 0)
  pthread_cond_wait(&c, &m); 
  pthread_mutex_unlock(&m); 
}

int main(int argc, char *argv[]) {
  printf("parent: begin\n"); 
  pthread_t p;
  pthread_create(&p, NULL, child, NULL);
  thr_join();
  printf("parent: end\n"); return 0;
}

Sorry, only read your title when I commented. Just to make sure I understand your order of operations, a long-winded version of the already-posted answer:

parent calls:

pthread_mutex_lock(&m); // locks the mutex
pthread_cond_wait(&c, &m);  // releases the mutex

child calls:

pthread_mutex_lock(&m);  // locks the mutex
pthread_cond_signal(&c); // does nothing to the mutex, it's still locked
// the parent thread has been signaled, but it is still blocked
// because it can't acquire the mutex.
// At this moment in time, the child still owns the mutex, so
// pthread_cond_wait cannot acquire it, thus the parent waits...

pthread_mutex_unlock(&m); // releases the mutex
// ok, the child released the mutex and the parent thread has been signaled.
// The mutex is available. pthread_cond_wait in the parent can
// acquire it and return.

parent calls:

// now that the mutex is unlocked, the parent can return from its
// pthread_cond_wait(&c, &m) call from above, which returns with the mutex
// locked. A successful call to pthread_cond_wait(..) returns with the
// mutex locked, so this can't successfully return until it acquires the
// mutex.
pthread_mutex_unlock(&m);  // releases the locked mutex, no UB

Of course, this is only one of several order of operations. I think your misunderstanding is that pthread_cond_wait can't return successfully until it acquires the mutex. At that point, it correctly calls pthread_mutex_unlock(&m); on a locked mutex.

So this would mean that the mutex is unlocked

No, pthread_cond_wait returns with mutex locked.

if parent_thread attempts to call pthread_mutex_unlock(&mutex)

Parent just unlocks the mutex after pthread_cond_wait returns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM