如何知道分离的std :: thread是否已完成执行?

时间:2019-02-18 15:22:58

标签: c++ multithreading stdthread

我有类似下面的功能,其中线程使用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
    // ...

}

1 个答案:

答案 0 :(得分:5)

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

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

另一种方法可能是使压缩线程保持活动状态,但是只要没有工作要做就将其阻塞。可以使用条件变量来通知该线程以开始其工作,并在完成操作后继续阻塞直到下一次通知。

P.S。您可能想要先关闭文件流,重命名文件,然后在按住锁的同时重新打开,以便在压缩先前的日志(现在位于重命名的文件中)的同时,其他线程可以继续登录到新文件中。