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

时间:2017-03-15 19:19:47

标签: c++ multithreading pthreads mutex

在多线程环境中,确保堆栈分配的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()函数的合法性,我想确保可执行文件不仅仅是似乎因为未定义的行为而起作用。

2 个答案:

答案 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;