Эффективно ли использование команды cat для объединения файлов, созданных несколькими потоками?

У меня есть многопоточная программа C ++ 11, в которой каждый поток создает большой объем данных, которые необходимо записать на диск. Все данные должны быть записаны в один файл. На данный момент я использую мьютекс, который защищает доступ к файлу из нескольких потоков. Мой друг предложил мне использовать один файл для каждого потока, а затем объединить файлы в один файл с cat Команда выполнена из кода C ++ с использованием system(),
Я думаю, если cat Команда собирается прочитать все данные с диска и затем снова записать их на диск, но на этот раз в один файл, лучше не будет. Я гуглил но не смог найти cat Детали реализации команды. Могу ли я знать, как это работает и собирается ли это ускорить всю процедуру?

Редактировать:
Хронология событий не важна, и нет никаких ограничений на порядок содержимого файлов. Оба метода будут выполнять то, что я хочу.

1

Решение

Вы не указываете, есть ли у вас какие-либо ограничения по упорядочению или структурированию содержимого файла. Обычно это так, поэтому я буду относиться к нему как к такому, но, надеюсь, мое решение должно работать в любом случае.

Классический программный подход

Идея состоит в том, чтобы перенести работу записи на диск в выделенный поток ввода-вывода и создать очередь из нескольких производителей / одного потребителя, чтобы поставить в очередь все команды записи. Каждый рабочий поток просто форматирует свой вывод в виде строки и возвращает его обратно в очередь. Поток ввода-вывода извлекает пакеты сообщений из очереди в буфер и выполняет команды записи.

В качестве альтернативы, вы можете добавить поле в ваши сообщения, чтобы указать, какой работник отправил команду записи, и, при необходимости, заставить поток ввода-вывода выдавать разные файлы.

Для повышения производительности также интересно взглянуть на асинхронные версии системных примитивов ввода-вывода (чтение / запись), если ваша хост-ОС их поддерживает. Поток ввода-вывода сможет контролировать несколько одновременных операций ввода-вывода и наполнять ОС новыми, как только завершится один.

Как было указано в комментариях, вам придется следить за потоком ввода-вывода на предмет перегрузок и соответственно настраивать количество рабочих. «Естественный» механизм, основанный на обратной связи, состоит в том, чтобы просто ограничить очередь, и рабочие будут ждать блокировки, пока на ней не освободится место. Это позволяет вам контролировать количество создаваемых данных в любой точке в течение срока службы процесса, что является важным моментом в сценариях с ограниченным объемом памяти.

Ваш cat проблемы

Что касается cat, этот инструмент командной строки просто прочитайте все, что написано на его входной канал (обычно stdin) и дублирует его на выходе (stdout). Это так просто, и вы можете ясно увидеть сходство с решением, предложенным выше. Разница в том, что cat не понимает внутреннюю структуру файла (если есть), он имеет дело только с байтовыми потоками, что означает, что если несколько процессов записывают одновременно в cat вход без синхронизации, полученный результат, вероятно, будет полностью перепутан. Другая проблема заключается в валентность (или его отсутствие) IO примитивов.


NB. В некоторых системах есть небольшая небольшая функция, которая называется вилка, что позволяет вам иметь несколько «независимых» потоков данных, мультиплексированных в одном файле. Если вам доведется работать на платформе, поддерживающей эту функцию, все ваши потоки данных могут быть объединены в один файл, но доступны по отдельности.

7

Другие решения