首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >未声明标识符“PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP”的使用

未声明标识符“PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP”的使用
EN

Stack Overflow用户
提问于 2018-10-31 02:13:10
回答 3查看 3.3K关注 0票数 2

我试着用gcc在macOS 10.14上编译,gcc在终端上。

我在我的C程序顶部包含了#define _GNU_SOURCE#include <pthread.h>

但是,当我使用以下内容:gcc input.c -o output -lpthread-pthread时,我会得到以下错误。我也试过用-std=c99

代码语言:javascript
运行
复制
input.c:50:33: error: use of undeclared identifier
'PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP'
pthread_mutex_t request_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

下面是我的代码摘要:

输入c:

代码语言:javascript
运行
复制
#define _GNU_SOURCE
#include <stdlib.h>
…
#include <pthread.h>

pthread_mutex_t request_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

int main(int argc, char* argv[])
{
  ...
}

编辑

通过在_NP的末尾移除PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,我能够让代码正常工作。谢谢大家的建议。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-31 03:52:48

_GNU_SOURCE不会做任何事情来显示Mac上的库扩展,因为Mac不是来自GNU项目,也不使用GNU库。

在Mac上,“显示扩展”特性选择宏是_DARWIN_C_SOURCE

然而,这并不一定会显示一个PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;我不认为它存在。当然,递归互斥类型PTHREAD_MUTEX_RECURSIVE是存在的;只是没有静态设置初始化器。必须移植代码以显式调用pthread_mutex_init来初始化其递归互斥项。

另一个想法是只编写不需要递归互斥的代码。递归互斥用于“分散脑”并发编程。“嗯,我不知道我是否已经有了这把锁,所以我会抓住它以防万一。”明智的选择是设计程序,让你知道!

递归互斥本质上是一种带宽辅助解决方案,适用于当遗留的单线程代码被转换为多线程时出现的某些情况。递归互斥在一个全新的设计中是不合适的。

如果避免递归互斥,则可以使用标准的PTHREAD_MUTEX_INITIALIZER

票数 1
EN

Stack Overflow用户

发布于 2018-10-31 03:47:48

PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP是一个非标准的扩展,显然MacOS不支持它.

相反,您应该在main()开头初始化您的互斥对象。

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>
#include <pthread.h>

pthread_mutex_t request_mutex;

int init_recursive_mutex(pthread_mutex_t *mutex)
{
    pthread_mutexattr_t attr;
    int r;

    r = pthread_mutexattr_init(&attr);
    if (r != 0)
        return r;

    r = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

    if (r == 0)
        r = pthread_mutex_init(mutex, &attr);

    pthread_mutexattr_destroy(&attr);

    return r;
}

int main(int argc, char* argv[])
{
    int r;

    r = init_recursive_mutex(&request_mutex);
    if (r != 0)
    {
        fprintf(stderr, "Failed to initialise request_mutex: %s\n", strerror(r));
        return 1;
    }

    /* ... */
}
票数 3
EN

Stack Overflow用户

发布于 2020-07-03 21:24:32

PTHREAD_RECURSIVE_MUTEX_INITIALIZER在OSX上是可用的,但只能从10.7开始,所以如果您必须支持早期版本,则必须在使用之前直接初始化互斥(如this answer中建议的@caf ),或者使用pthread_once延迟初始化互斥

代码语言:javascript
运行
复制
#if ((__MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) || defined(__DRIVERKIT_VERSION_MIN_REQUIRED)

static pthread_mutex_t s_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;

int lock() {
  return pthread_mutex_lock(&s_mutex);
}

int unlock() {
  return pthread_mutex_unlock(&s_mutex);
}

#else

static pthread_mutex_t s_mutex;
static pthread_once_t s_mutex_init = PTHREAD_ONCE_INIT;

static void init_mutex() {
  init_recursive_mutex(&s_mutex);
} 

int lock() {
  pthread_once(&s_mutex_init, init_mutex);
  return pthread_mutex_lock(&s_mutex);
} 

int unlock() {
  return pthread_mutex_unlock(&s_mutex);
}

#endif
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53075327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档