首页 > 解决方案 > 如何知道分离的 std::thread 是否已完成执行?

问题描述

我有一个类似以下的函数,其中线程通过使用 std::lock_guard 互斥锁获取锁并通过 ofstream 写入文件。

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

如果日志文件很大(比如 ~500MB),压缩大约需要 25 秒以上。我分离了压缩线程,因为没有其他线程(或主线程)想要等待该线程完成。

但我需要知道在执行以下行之前压缩线程没有运行:

_compress_thread(compress_log, _logfile).detach();

示例代码片段:

    void log (std::string message)
    {
        // Lock using mutex
        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) {
            // Code to close the file stream, rename the file, and reopen
            ...


            // Create an independent thread to compress the file since
            // it takes some time to compress huge files.
            if (the_compress_thread_is_not_already_running) //pseudo code
            {
                _compress_thread(compress_log, _logfile).detach();
            }
        }
    }

在上述if情况下the_compress_thread_is_not_already_running,我如何确定压缩线程没有运行?

void * compress_log (std::string s) 
{

    // Compress the file
    // ...

}

标签: c++multithreadingstdthread

解决方案


无法检测分离的执行线程是否已终止。

如果您出于某种原因需要保证最多一个线程同时压缩,那么一个简单的解决方案是使用std::async. 它返回一个未来对象。您可以查询未来对象关联的回调是否已完成。通过在函数末尾修改共享变量(请注意,共享访问必须同步),可以使用分离线程以较少结构化的方式实现相同的效果。

另一种方法可能是不断保持压缩线程处于活动状态,但只要没有工作要做就阻止它。可以使用条件变量通知线程以开始其工作,一旦完成,继续阻塞直到下一次通知。

PS您可能希望首先关闭文件流,重命名文件,然后在您持有锁定时重新打开,以便其他线程可以在先前的日志(现在在重命名的文件中)被压缩时继续登录到新文件。


推荐阅读