Как сжать файл неблокирующим способом - PullRequest
0 голосов
/ 04 февраля 2019

У моего приложения есть класс, в котором есть метод, который записывает в файл с использованием std :: ofstream.

Это многопоточное приложение, и многие потоки могут одновременно вызывать функцию log ().Поэтому я добавил мьютекс std :: lock_guard в функцию log ().

Эти потоки также могут быть временными, что означает, что нет необходимости, чтобы они жили до тех пор, пока существует родительский процесс.

Как только размер файла достигнет максимального настроенного значения, его следует переименовать и сжать.

Размер файла может достигать 1 ГБ.И GZIP занимает более 20 секунд, чтобы сжать это.

Поэтому резьба блокируется, пока gzip не завершит сжатие.

Я ищу способ, которым файл может быть сжат неблокирующим способом с сохранением защиты std :: lock_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) {
          ;
        }
    }
}

1 Ответ

0 голосов
/ 04 февраля 2019
  • Взять блокировку
  • Закрыть поток
  • Переименовать файл
  • Открыть поток
  • Снять блокировку
  • Сжатие переименованного файла без блокировки писателей
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...