You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Introduction

Whenever threads come into play, there are bounded to be shared memory or resources that each thread wants to access. But because of the random nature of execution of each thread, there will be corruption of data when multiple threads try to read and write into the same memory space. One possible way to fix the problem is using locking mechanism like a mutex. POSIX provides a mutex called pthread_mutex_t just for this purpose.

Deadlock can happen when multiple threads each holds a lock the other needs and are waiting for each other to release the resource. One way to fix the problem is to avoid circular wait by locking the mutex in a predefined order.

Noncompliant Code Example

#include <pthread.h>

void *thread1(void *ptr);
void *thread2(void *ptr);

pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;

void *thread1(void *ptr) {

  pthread_mutex_lock(&m1);
  /* do some stuff that require locking mutex1 */

  pthread_mutex_lock(&m2);
  /* do some stuff that require locking mutex2 */

  pthread_mutex_unlock(&m2);
  pthread_mutex_unlock(&m1);

  return NULL;
}

void *thread2(void *ptr) {

  pthread_mutex_lock(&m2);
  /* do some stuff that require locking mutex2 */

  pthread_mutex_lock(&m1);
  /* do some stuff that require locking mutex1 */

  pthread_mutex_unlock(&m1);
  pthread_mutex_unlock(&m2);

  return NULL;
}

Compliant Solution

#include <pthread.h>

void *thread1(void *ptr);
void *thread2(void *ptr);

pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;

void *thread1(void *ptr) {

  pthread_mutex_lock(&m1);
  pthread_mutex_lock(&m2);

  /* do some stuff that require locking mutex1 */
  /* do some stuff that require locking mutex2 */

  pthread_mutex_unlock(&m2);
  pthread_mutex_unlock(&m1);

  return NULL;
}

void *thread2(void *ptr) {

  pthread_mutex_lock(&m1);
  pthread_mutex_lock(&m2);
  /* do some stuff that require locking mutex1 */
  /* do some stuff that require locking mutex2 */

  pthread_mutex_unlock(&m1);
  pthread_mutex_unlock(&m2);

  return NULL;
}

  • No labels