【问题标题】:How to compress file in non-blocking way如何以非阻塞方式压缩文件
【发布时间】:2019-02-04 19:54:59
【问题描述】:

我的应用程序有一个类,该类有一个使用 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) {
          ;
        }
    }
}

【问题讨论】:

  • 我认为您应该在开始异步压缩之前重命名文件并为传入日志打开一个新文件
  • 除了@OznOg 所说的之外,您还可以在额外的线程中进行压缩。

标签: c++ file compression


【解决方案1】:
  • 拿锁
  • 关闭信息流
  • 重命名文件
  • 重新打开流
  • 解除锁定
  • 在不阻塞作者的情况下压缩重命名的文件

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多