首页 > 解决方案 > 当 std::lock_guard 仍在范围内时,使用 pthread_create 创建线程是否安全?

问题描述

我有一个类似下面的函数,其中线程通过使用std::lock_guard互斥锁获取锁并通过ofstream.

当当前文件大小增加最大大小时,我想创建一个应该压缩文件并终止的独立线程。

我想了解调用pthread_createwhenstd::lock_guard仍在范围内的含义。

安全吗?锁是否也会应用于新线程(我不打算这样)?

void log (std::string message)
{
    std::lock_guard<std::mutex> lck(mtx);

    _outputFile << message << std::endl;
    _outputFile.flush();
    _sequence_number++;
    _curr_file_size = _outputFile.tellp();

    if (_curr_file_size >= max_size) {
        char *lf = strdup(_logfile.c_str());
        // Create an independent thread to compress the file since
        // it takes some time to compress huge files.
        if (!_compress_thread) {
            pthread_create(&_compress_thread, NULL, compress_log, (void *)lf);
        }
    }
}

void * compress_log (void *arg) 
{
    pthread_detach(pthread_self());

    // Code to compress the file
    // ...

   { // Create a scope for lock_gaurd

       std::lock_guard<std::mutex> lck(mtx);
       _compress_thread = NULL;
   }
   pthread_exit(NULL);
}

标签: c++multithreadingpthreads

解决方案


互斥体在线程级别工作,它只影响使用它的线程。当一个线程锁定一个互斥体时,会发生两件事:

  1. 互斥锁被解锁 - 它被锁定并且线程继续执行。
  2. 互斥体已被锁定 - 线程不会继续,而是等待互斥体解锁。

您的新线程运行该compress_log()函数,该函数根本不访问互斥锁。因此,无论互斥锁是否被锁定,它都会运行(在您的情况下,互斥锁将在log()退出时解锁)。


一个不相关的建议:使用std::thread而不是pthread_create,这样您的应用程序变得更加可移植:

    std::thread{ [lf] { compress_log(lf); } }.detach();

推荐阅读