在多线程环境中,确保堆栈分配的pthread_mutex_t对象只初始化一次的可行/标准方法是什么?
pthread_mutex_init()
手册页说:
尝试初始化已初始化的互斥锁导致 未定义的行为。
我有一个.cpp
文件,该文件被编译为共享库。这个文件的简化是:
#include <pthread.h>
static pthread_mutex_t g_mutex;
int initialize()
{
pthread_mutex_init( &g_mutex, NULL );
pthread_mutex_lock( &g_mutex );
// Do init stuff.
pthread_mutex_unlock( &g_mutex );
return 0;
}
可以在多线程环境中调用 initialize()
。因此,pthread_mutex_init()
可以在同一个对象上被多次调用,这是未定义的行为,如上所述。所以这需要线程安全......通过使用另一个互斥锁。但是后来谁以线程安全的方式初始化那个互斥锁,无限期地......?
在全局范围内调用pthread_mutex_init()
是否合法(即与pthread_mutex_t
对象声明的范围相同),如下所示,这被视为&#34;正确&#34;解决这种情况?
#include <pthread.h>
static pthread_mutex_t g_mutex;
static int g_res = pthread_mutex_init( &g_mutex, NULL );
int initialize()
{
// g_mutex already initialized (?) so no need to do so here.
pthread_mutex_lock( &g_mutex );
// Do init stuff.
pthread_mutex_unlock( &g_mutex );
return 0;
}
我尝试了什么:
我编译并运行了第二个代码块,这两个代码块都成功了。
但是我仍然想问社群,因为我不清楚在全球范围内调用pthread_mutex_init()
函数的合法性,我想确保可执行文件不仅仅是似乎因为未定义的行为而起作用。
答案 0 :(得分:1)
static int g_res = pthread_mutex_init( &g_mutex, NULL );
在C ++代码中很好,但在C代码中不起作用(是的,你的代码是纯C ++,但是有人会在C语言中尝试...)
对于每个the POSIX standard的C(或C ++中的替代):
...
如果默认互斥锁属性合适,则为宏 PTHREAD_MUTEX_INITIALIZER可用于初始化互斥锁。该 效果应相当于通过调用动态初始化 pthread_mutex_init(),参数attr指定为NULL。 ...
像这样:
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
答案 1 :(得分:1)
在全局范围内调用
pthread_mutex_init()
是否合法(即与pthread_mutex_t
对象声明的范围相同),如下所示,这被视为&#34;正确&#34;解决这种情况?
在C语言中不合法,但在C ++中它没有问题。但是,由于您使用默认属性初始化互斥锁,因此最好使用初始化程序宏:
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;