我正在尝试在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
来使代码正常工作。谢谢大家的建议。
答案 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