如何确保共享堆栈分配pthread_mutex_t的单一初始化? (C++)

How to ensure single initialization of shared stack-allocated pthread_mutex_t? (C++)

什么是 advisable/standard 确保堆栈分配的 pthread_mutex_t 对象在多线程环境中仅初始化一次的方法?

pthread_mutex_init() 手册页说:

Attempting to initialise an already initialised mutex results in undefined behaviour.

我有一个 .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_t 对象声明相同的范围)调用 pthread_mutex_init() 是否合法,这是否被认为是此问题的 "correct" 解决方案情况?

#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() 函数的合法性,我想确保可执行文件不只是出现由于未定义的行为而工作。

static int g_res = pthread_mutex_init( &g_mutex, NULL );

在 C++ 代码中很好,但在 C 代码中不起作用(是的,您的代码是纯 C++,但有人会在 C 中尝试...)

根据 the POSIX standard:

对于 C(或 C++ 中的替代方案)

...

In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes. The effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL. ...

像这样:

static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;

Is it legal to call pthread_mutex_init() at the global scope (i.e. the same scope as the pthread_mutex_t object declaration) as below, and is this considered a "correct" solution to this situation?

这在 C 中是不合法的,但在 C++ 中是可以的。但是,由于您正在使用默认属性初始化互斥锁,因此最好使用初始化宏:

static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;