Mutex and POSIX in Multithreading

What is Mutex?

  • Mutex is a synchronization primitive used for interprocess synchronization.
  • Mutex is an abbreviation for “mutual exclusion”. It is a mechanism that acts as a flag to prevent two threads from performing one or more actions simultaneously.
  • Mutex is a lock and only state that is locked or unlocked is associated with it, so the recursive mutex can be locked more than once. The programmer has to unlock the mutex as many number times as it was locked.
  • Mutex is used to avoid simultaneous use of resources such as global variables by the critical sections.
  • Critical section is a piece of code where a process or thread accesses a common resource.
  • The mutex lock ensures that only one thread has permission to access a resource at a time.
  • Mutexes can be shared between processes where critical sections cannot be shared between processes, so the performance overhead of critical section is lower.

Synchronization with Mutex

  • System needs synchronization when two or more threads need to access a shared resource at the same time.
  • Synchronization ensures that only one thread at a time uses the resource.
  • Mutex is a synchronization primitive used to protect shared data from simultaneous access.
  • Mutex lock acquires only one thread at a time. For other threads to get the same mutex, they must wait until it is released by the current owner of the mutex.
  • The mutex is locked for controlling to access before entering the section of the code and then unlock it when finished. Following code shows the synchronizing access with mutexes.

  • int pthread_mutex_init(pthread_mutex_t *m_mutex, const pthread_mutexattr_t *mutexattr);

    int pthread_mutex_lock(pthread_mutex_t *m_mutex);

    int pthread_mutex_unlock(pthread_mutex_t *m_mutex);

    int pthread_mutex_destroy(pthread_mutex_t *m_mutex);

    In the above code, all the functions has a pointer to a previously declared object. The pthread_mutex_init allows to provide attributes for the mutex which controls its behavior
Following are the two types of Synchronization:
1. Mutual Exclusion
2. Condition Synchronization

1. Mutual Exclusion

  • Mutual exclusion ensures that all threads see a self-consistent view of the shared data without any broken invariants.
  • Mutex is important to structure the program code to protect the right data and to avoid race conditions inherent in the interfaces. Mutex is the data protection mechanism.
  • Mutex protects either too much or too little data because sometimes it comes with own problems in the form of a deadlock.

2. Condition Synchronization

  • Condition synchronization ensures that the state of a program satisfies a particular condition before some action occurs.
  • It provides a different types of synchronization than a mutex and semaphore lock. (Semaphore can be used to condition sync by signaling the condition to other threads.)

What is POSIX?

  • POSIX threads or Pthreads define an API for creating and manipulating threads.
  • The APIs are available on many Unix-like POSIX systems such as FreeBSD, NetBSD, GNU/Linux, Mac OS X and Solaris.
  • The latest version of POSIX.1c standard extension is IEEE STD 1003.1, 2004.
  • It is a POSIX standard for threads.
  • They are defines as a set of C language programming types and procedure calls and implemented with a pthread.h header file.
  • The functions of pthread are not included in the standard C library. It is included in the libpthrea and threfore the -lpthread will be added to link the program.
pthread_create (thread, attr, start_routine, arg)

pthreadIt creates a new thread and makes it executable.
threadIt is an unique identifier for the new thread returned by the subroutine.
attrIt is an attribute object used to set thread attributes.
start_routineIt defines the C++ routine that the thread will execute once it is created.
argIt defines a single argument that may be passed to start_routine.

Following are the pthread APIs:

Pthread APIDescription
Thread ManagementIn thread management, routine directly works (such as creating, detaching, joining etc.) on threads.

It includes function to set/query thread attributes such as joinable, scheduling etc.
MutexRoutine deals with synchronization is called a Mutex.

It is an abbreviation for “mutual exclusion”.

The functions of mutex are provide for creating, destroying, locking and unlocking mutexes.

It is used to protect shared data from simultaneous access. It can be locked and unlocked. Once it is locked, current thread owns mutex until it is not unlocked. It means that no other thread can execute any instructions from the block of code surrounded by mutex until thread that owns mutex unlocks it.

The <mutex> header file is used if you want to use mutex.
Condition VariablesIn condition variables, routine address communication is done between threads that share a mutex.

It is based upon program specified conditions.

It includes create, destroy, wait and signal based upon specified variable values.
SynchronizationIn synchronization, routine manages read/write locks and barriers.

Terminating Thread

Following are the several ways in which a pthread may be terminated
  • A thread returns from its starting routine and makes a call to the pthread_exit subroutine.
  • Using pthread_cancel routine thread is canceled by another thread.
  • The whole process is terminated due to a call to either the exec or exit subroutines.
  • The pthread_exit routine is used to exit a thread. This routine is called after a thread has completed its work and is no longer required to exist.
  • The pthread_exit routine does not close files. If any files opened inside the thread, it will remain open after the thread is terminated.
    pthread_exit (status)
  • The above example defines termination of a POSIX thread.
  • The programmer may optionally specify a termination status stored as a void pointer for any thread that may join the calling thread.
  • If main() function finishes before the threads which it has created and exits with pthread_exit() then the other threads will continue to execute. Otherwise, they will be terminated automatically when main() function finishes.

Joining Threads

  • When a thread is created, one of its attributes defines whether it is joinable or detached.
    pthread_join (threadid, status)
  • Only joinable threads can be joined if they are created as a joinable.
  • If a thread is created as detached, it can never be joined.
  • The final draft of the POSIX standard specifies that the threads are created as joinable.

Detaching Threads

  • The pthread_detach() routine is used to detach a thread even though it was created as joinable.
  • In detaching, there is no converse routine.
  • The detach() function detaches a thread from the parent thread.
  • This function allows parent and child threads to be executed independently from each other.