54

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

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

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

4

4 回答 4

90

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
于 2011-11-01T07:53:17.773 回答
18

要创建递归互斥锁,请使用:

#include <pthread.h>
int pthread_mutexatttr_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);
于 2011-08-12T08:35:41.433 回答
17

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

static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

(顺便说一下,这个例子来自pthread_mutex_init(3) 手册页!)

于 2011-10-28T19:42:53.390 回答
2

创建互斥体时需要添加互斥体属性。

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

于 2011-08-12T08:37:31.413 回答