Skip to main content
Engineering LibreTexts

9.5: Mutex

  • Page ID
    40764
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    My definition of Mutex is a wrapper for a type called pthread_mutex_t, which is defined in the POSIX threads API.

    To create a POSIX mutex, you have to allocate space for a pthread_mutex_t type and then call pthread_mutex_init.

    One of the problems with this API is that pthread_mutex_t behaves like a structure, so if you pass it as an argument, it makes a copy, which makes the mutex behave incorrectly. To avoid that, you have to pass pthread_mutex_t by address.

    My code makes it easier to get that right. It defines a type, Mutex, which is just a more readable name for pthread_mutex_t:

    #include <pthread.h>
    
    typedef pthread_mutex_t Mutex;
    

    Then it defines make_mutex, which allocates space and initializes the mutex:

    Mutex *make_mutex()
    {
        Mutex *mutex = check_malloc(sizeof(Mutex));
        int n = pthread_mutex_init(mutex, NULL);
        if (n != 0) perror_exit("make_lock failed"); 
        return mutex;
    }
    

    The return value is a pointer, which you can pass around as an argument without causing unwanted copying.

    The functions to lock and unlock the mutex are simple wrappers for POSIX functions:

    void mutex_lock(Mutex *mutex)
    {
        int n = pthread_mutex_lock(mutex);
        if (n != 0) perror_exit("lock failed");
    }
    
    void mutex_unlock(Mutex *mutex)
    {
        int n = pthread_mutex_unlock(mutex);
        if (n != 0) perror_exit("unlock failed");
    }
    

    This code is in mutex.c and the header file mutex.h.


    This page titled 9.5: Mutex is shared under a CC BY-NC license and was authored, remixed, and/or curated by Allen B. Downey (Green Tea Press) .

    • Was this article helpful?