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

时间:2018-10-31 02:13:10

标签: c pthreads

我正在尝试在macOS 10.14上使用gcc在终端中使用gcc进行编译。

我已将-放在C程序的顶部,并且#define _GNU_SOURCE

但是当我使用以下命令时:#include <pthread.h>gcc input.c -o output -lpthread会出现以下错误。我也尝试过使用-pthread

-std=c99

这是我的代码摘要:

input.c:

input.c:50:33: error: use of undeclared identifier
'PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP'
pthread_mutex_t request_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

修改

我可以通过在#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来使代码正常工作。谢谢大家的建议。

3 个答案:

答案 0 :(得分:3)

PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP是非标准扩展,显然MacOS不支持它。

您应该在main()的开头初始化互斥锁:

#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;
    }

    /* ... */
}

答案 1 :(得分:1)

class MeanEncoding(BaseEstimator, TransformerMixin): def fit(self, X, y=None): return self def transform(self, X): tmp = X['AreaCode1'].map(X.groupby('AreaCode1')['isFail'].mean()) return tmp.values.reshape(len(tmp), 1) 不会做任何事情来揭示Mac OS上的库扩展,因为Mac OS不是来自GNU项目,也不使用GNU C库。

在Mac OS上,“显示扩展程序”功能选择宏为_GNU_SOURCE

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

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

对于将传统单线程代码转换为多线程时出现的某些情况,递归互斥锁本质上是一种创可贴解决方案。递归互斥锁在全新设计中不合适。

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

答案 2 :(得分:0)

PTHREAD_RECURSIVE_MUTEX_INITIALIZER在OSX上可用,但仅从10.7开始,因此,如果必须支持早期版本,则必须在使用前直接初始化互斥锁(例如this answer中建议的@caf)或使用pthread_once惰性地初始化它:

#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