如何使用 POSIX 线程声明递归互斥体?

问题描述 投票:0回答:4

我对如何使用 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

所以我尝试做的就是连续读取/从队列中删除。

问题是没有任何关于如何声明递归互斥体的例子。或者可能有一些,但他们不为我编译。

c multithreading pthreads mutex recursive-mutex
4个回答
93
投票

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

20
投票

要创建递归互斥锁,您可以使用:

#include <pthread.h>
/* Don't forget to check the return value! */
int pthread_mutexattr_settype(pthread_mutexattr_t *attr,
                               int 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);

18
投票

在 Linux 上(但这不能移植到其他系统),如果互斥量是全局或静态变量,您可以像

一样初始化它
static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

(顺便说一句,这个例子来自

pthread_mutex_init(3)
man页面!)


2
投票

创建互斥量时需要添加互斥量属性

调用

pthread_mutexattr_init
,然后用
pthread_mutexattr_settype
调用
PTHREAD_MUTEX_RECURSIVE
,然后用
pthread_mutex_init
使用这些属性。阅读
man pthread_mutexattr_init
了解更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.