以某种方式在C++中错误地使用互斥锁

ale*_*ale 3 c++ pthreads

我有以下代码尝试(和失败)来保护我的代码中的关键区域.基本上我想在任何其他线程打印另一个语句之前由任何线程完全执行print语句.

main.h:

pthread_mutex_t printer_mutex;
Run Code Online (Sandbox Code Playgroud)

main.c- 程序的第一件事:

pthread_mutex_init(&printer_mutex, NULL);
Run Code Online (Sandbox Code Playgroud)

线程是这样创建的(虽然我删除了一些检查):

for(long t = 0; t < NUM_THREADS; t++) {
   args[t].fw = fw;
   args[t].deriv_init = deriv_init;
   args[t].to_prove = fw.to_prove.at(i);
   pthread_create(&threads[t], NULL, do_derivation_helper, (void *) &args[t]);
}
for(long t = 0; t < NUM_THREADS; t++) {
  pthread_join(threads[t], NULL);
}
Run Code Online (Sandbox Code Playgroud)

然后在我的一个类中执行程序中的所有打印,我有以下内容.打印应该锁定,然后在完成后解锁.

void InfoViewer::rule_x_fires() {
    // START CRITICAL REGION
    pthread_mutex_lock(&printer_mutex);
    cout << "INFO: Rule x fires" << endl;
    pthread_mutex_unlock(&printer_mutex);
    // END CRITICAL REGION
}
Run Code Online (Sandbox Code Playgroud)

我得到的不良输出是:

INFO: Rule x firesINFO: Rule x fires
Run Code Online (Sandbox Code Playgroud)

即,在其他线程开始打印之前,该行未结束.

有任何想法吗?我没有正确初始化吗?我可以在我的C++程序中使用标准的C风格线程吗?

Nik*_*sov 8

我认为问题在于在头文件中定义互斥变量.这样每个编译单元都可以获得自己的变量版本,并且只需锁定不同的互斥锁即可.只需这样做:

// .h header file: declare
extern pthread_mutex_t printer_mutex;

// one of the .c/.cpp files: define
pthread_mutex_t printer_mutex;
Run Code Online (Sandbox Code Playgroud)

编辑0:

为了解释为什么它与多个定义"起作用" - 可以用两种不同的方式初始化PThread互斥体 - 动态地pthread_mutex_init和静态地PTHREAD_MUTEX_INITIALIZER.查看pthread.h一个可以找到以下(32位版本):

# define PTHREAD_MUTEX_INITIALIZER \
    { { 0, 0, 0, 0, 0, { 0 } } }
Run Code Online (Sandbox Code Playgroud)

这意味着任何类型的静态变量都pthread_mutex_t将被正确初始化,而不会分配任何显式值,或者由于静态内存为零填充而导致初始化.因此,您显式动态初始化了一个互斥锁,其他所有互斥锁都被隐式初始化为全零.