Mutex Class in C++
When multiple threads want to synchronize access to a shared resource they use mutexes and condition variables. A mutex enables a thread to block other threads from accessing a shared resource, while a condition variable is used by a thread to make itself wait for the state of a resource to be changed by other threads.
In my next two blogs I’ll illustrate how to simplify Pthread mutex and condition variable functions by wrapping them in C++ classes, starting with mutexes.
Pthread Mutex Functions
These are the standard Pthread functions that will be incorporated in the Mutex class.
#include <pthread.h>
/* Create a mutex */
int pthread_mutex_init(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr);
/* Locks the mutex blocking on it until the lock is acquired */
int pthread_mutex_lock(pthread_mutex_t *mutex);
/* Attempt to lock a mutex without blocking */
int pthread_mutex_trylock(pthread_mutex_t *mutex);
/* Unlocks a mutex */
int pthread_mutex_unlock(pthread_mutex_t *mutex);
/* Deletes a mutex */
int pthread_mutex_destroy(pthread_mutex_t *mutex);
Each function returns 0
if successful or an error number if it fails.
Mutex Class
The Mutex
class provides a method that wraps each of the Pthread mutex functions and contains a private pthread_mutex_t
variable which is use by the function calls. This hides the parameter so applications that call the Mutex
class methods do not have to provide it. Note that I declare a friend class CondVar
which will need to have access to the private m_mutex
data member as you’ll see in my next blog.
Owing to its simplicity the class can be defined in a single include file Mutex.h. Each method simply calls the corresponding Pthread mutex function and returns whatever it returns. When pthread_mutex_init()
is called, the attribute argument is set to NULL
to accept the default behavior.
#include <pthread.h>
class Mutex
{
friend class CondVar;
pthread_mutex_t m_mutex;
public:
// just initialize to defaults
Mutex() { pthread_mutex_init(&m_mutex, NULL); }
virtual ~Mutex() {
pthread_mutex_unlock(&m_mutex);
pthread_mutex_destroy(&m_mutex);
}
int lock() { return pthread_mutex_lock(&m_mutex); }
int trylock() { return pthread_mutex_trylock(&m_mutex); }
int unlock() { return pthread_mutex_unlock(&m_mutex); }
};
Mutex Test Application
You can get the source code for this project from GitHub – https://github.com/vichargrave/mutex.
The Mutex
class test program relies on my Thread
class which I wrote about awhile back. The application declares a MutexTest thread class which works with the main()
thread to lock a single Mutex
object.
The trick here is to give the MutexTest thread time to lock the Mutex
before main()
so we see the main thread waiting to acquire lock. So after creating the MutexTest thread, main()
sleeps for 1 second during which time the MutexTest
thread acquires the lock. MutexTest
then sleeps 10 seconds before unlocking the Mutex
at which point main()
acquires the lock and proceeds to run.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "thread.h"
#include "mutex.h"
class MutexTest : public Thread
{
Mutex &m_mutex;
public:
MutexTest(Mutex& mutex) : m_mutex(mutex) {}
void* run() {
printf("thread waiting to get mutex\n");
m_mutex.lock();
printf("thread got mutex lock\n");
// hold lock for awhile to make main thread wait
sleep(10);
m_mutex.unlock();
return NULL;
}
};
int main(int argc, char** argv)
{
Mutex mutex;
MutexTest test(mutex);
test.start();
// give the test thread a chance to acquire lock first
sleep(1);
// now it's main thread's turn
printf("main waiting to get mutex\n");
mutex.lock();
printf("main got mutex lock\n");
mutex.unlock();
test.join();
exit(0);
}
When the test application is run, the output looks like this after 1 second:
thread waiting to get mutex
thread got mutex lock
main waiting to get mutex
This indicates the Mutex is working. The application pauses at this point while main() waits 10 seconds to acquire the lock. When this time elapses the output looks like this:
thread waiting to get mutex
thread got mutex lock
main waiting to get mutex
main got mutex lock
Leave a comment