C语言 如何用POSIX线程声明递归互斥体?

dw1jzc5e  于 2023-03-28  发布在  其他
关注(0)|答案(4)|浏览(157)

我对如何使用pthread声明递归互斥有点困惑。我试图做的是一次只有一个线程能够运行一段代码(包括函数),但在怀疑之后,我发现使用互斥是行不通的,我应该使用递归互斥。下面是我的代码:

pthread_mutex_lock(&mutex);                   // LOCK

item = queue_peek(queue);                     // get last item in queue
item_buff=item;                               // save item to a buffer
queue_removelast(queue);                      // remove last item from queue

pthread_mutex_unlock(&mutex);                 // UNLOCK

所以我尝试做的只是从队列中连续读取/删除。
问题是没有任何关于如何声明递归互斥锁的例子,或者可能有一些,但它们对我来说无法编译。

2exbekwf

2exbekwf1#

来自Michael Foukarakis的代码几乎是好的,但他初始化互斥两次,导致未定义的行为。它应该是:

pthread_mutex_t Mutex;
pthread_mutexattr_t Attr;

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

我实际上在生产中使用了这段代码,而且我知道它在Linux、Solaris、HP-UX、AIX、Mac OSX和FreeBSD上都能正常工作。
你还需要添加适当的链接器标志来编译这个:

AIX, Linux, FreeBSD:
CPLATFORM += -pthread

mingw32:
LDFLAGS += -lpthread
j5fpnvbx

j5fpnvbx2#

要创建递归互斥体,您可以用途:

#include <pthread.h>
/* Don't forget to check the return value! */
int pthread_mutexatttr_settype(pthread_mutexattr_t *attr,
                               int type);

其中type是PTHREAD_MUTEX_RECURSIVE,或者是一个初始化器。
例如:

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

或者,在运行时初始化(不要两者都做,这是未定义的行为):

pthread_mutexattr_init(&mta);
/* or PTHREAD_MUTEX_RECURSIVE_NP */
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);

pthread_mutex_init(&mutex, &mta);
i2loujxw

i2loujxw3#

在Linux上(但这不能移植到其他系统),如果互斥体是一个全局或静态变量,您可以像下面这样初始化它:

static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

(and顺便说一下,这个例子来自pthread_mutex_init(3)man pages!)

pkmbmrz7

pkmbmrz74#

创建互斥锁时需要添加互斥锁属性。
调用pthread_mutexattr_init,然后使用PTHREAD_MUTEX_RECURSIVE调用pthread_mutexattr_settype,然后将这些属性与pthread_mutex_init一起使用。阅读man pthread_mutexattr_init以获取更多信息。

相关问题