C: How do you declare a recursive mutex with POSIX threads?

后端 未结 4 902
忘了有多久
忘了有多久 2020-12-07 17:47

I am a bit confused on how to declare a recursive mutex using pthread. What I try to do is have only one thread at a time be able to run a piece of code(including functions)

相关标签:
4条回答
  • 2020-12-07 18:14

    To create a recursive mutex, use:

    #include <pthread.h>
    int pthread_mutexatttr_settype(pthread_mutexattr_t *attr,
                                   int type);
    

    where type is PTHREAD_MUTEX_RECURSIVE.

    Don't forget to check the return value!

    Example:

    /* or PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
    pthread_mutex_t       mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutexattr_t   mta;
    

    or alternatively, initialize at runtime (don't do both, it's undefined behaviour):

    pthread_mutexattr_init(&mta);
    /* or PTHREAD_MUTEX_RECURSIVE_NP */
    pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
    
    pthread_mutex_init(&mutex, &mta);
    
    0 讨论(0)
  • 2020-12-07 18:17

    On Linux (but this is non portable to other systems), if the mutex is a global or static variable, you could initialize it like

    static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
    

    (and by the way, the example is from pthread_mutex_init(3) man pages!)

    0 讨论(0)
  • 2020-12-07 18:18

    You need to add mutex attributes when creating the mutex.

    Call pthread_mutexattr_init, then pthread_mutexattr_settype with PTHREAD_MUTEX_RECURSIVE then use these attributes with pthread_mutex_init. Read man pthread_mutexattr_init for more info.

    0 讨论(0)
  • 2020-12-07 18:26

    The code from Michael Foukarakis is almost good but he initializes the mutex twice which leads to undefined behavior. It should just be:

    pthread_mutex_t Mutex;
    pthread_mutexattr_t Attr;
    
    pthread_mutexattr_init(&Attr);
    pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&Mutex, &Attr);
    

    I actually use this code in production, and I know it works correctly on Linux, Solaris, HP-UX, AIX, Mac OSX and FreeBSD.

    You also need to add proper linker flag to compile this:

    AIX, Linux, FreeBSD:
    CPLATFORM += -pthread
    
    mingw32:
    LDFLAGS += -lpthread
    
    0 讨论(0)
提交回复
热议问题