我的应用程序有一个类,该类具有使用std :: ofstream写入文件的方法。

这是一个多线程应用程序,许多线程可以同时调用log()函数。因此,我在log()函数中添加了一个std :: lock_guard互斥量。

这些线程也可以是瞬态的,这意味着只要父进程存在,它们就不必生存。

文件大小达到最大配置值后,应重命名并压缩。

文件大小可以高达1GB。而gzip需要20秒钟以上的时间来进行压缩。

因此,线程被阻塞,直到gzip完成压缩。

我正在寻找一种以非阻塞方式压缩文件的方式,以保持std :: lock_guard guard(_log_mutex);心里。

class Logger {
    std::string   _logfile;
    std::mutex    _log_mutex;
    uint64_t      _sequence_number;
    std::ofstream::pos_type _curr_size;

 public:
    void log (std::string message)
    {
        // Take the lock
        std::lock_guard<std::mutex> guard(_log_mutex);

        // If size exceeds max then close, rename, and compress.
        if (_curr_size >= MAX_FILE_SIZE) {
            _outputFile.close();

            // Code already in place to rename the file.

            // Compress _logfile ???

            _outputFile.open(_logfile, std::ios::app);
            _curr_size = _outputFile.tellp();
        }

        _outputFile << _sequence_number << " : " << message << std::endl;
        _outputFile.flush();
        _curr_size = _outputFile.tellp();
        _sequence_number++;
    }

    // Other stuffs...
    ...
};


我尝试了以下操作,但它仍然阻塞了线程:

compress_file(const char *file_name) {
    pid_t pid;

    pid = fork();

    if (!pid) {
        execl("/usr/bin/gzip", "gzip", "-f", file_name, NULL);
        exit(1);
    } else {
        while (wait3(NULL, WNOHANG, NULL) > 0) {
          ;
        }
    }
}

最佳答案

拿锁
关闭流
重命名文件
重新打开流
释放锁
压缩重命名的文件而不会阻止编写器

10-07 20:12
查看更多