У меня есть многопоточная программа C ++ 11, в которой каждый поток создает большой объем данных, которые необходимо записать на диск. Все данные должны быть записаны в один файл. На данный момент я использую мьютекс, который защищает доступ к файлу из нескольких потоков. Мой друг предложил мне использовать один файл для каждого потока, а затем объединить файлы в один файл с cat
Команда выполнена из кода C ++ с использованием system()
,
Я думаю, если cat
Команда собирается прочитать все данные с диска и затем снова записать их на диск, но на этот раз в один файл, лучше не будет. Я гуглил но не смог найти cat
Детали реализации команды. Могу ли я знать, как это работает и собирается ли это ускорить всю процедуру?
Редактировать:
Хронология событий не важна, и нет никаких ограничений на порядок содержимого файлов. Оба метода будут выполнять то, что я хочу.
Вы не указываете, есть ли у вас какие-либо ограничения по упорядочению или структурированию содержимого файла. Обычно это так, поэтому я буду относиться к нему как к такому, но, надеюсь, мое решение должно работать в любом случае.
Классический программный подход
Идея состоит в том, чтобы перенести работу записи на диск в выделенный поток ввода-вывода и создать очередь из нескольких производителей / одного потребителя, чтобы поставить в очередь все команды записи. Каждый рабочий поток просто форматирует свой вывод в виде строки и возвращает его обратно в очередь. Поток ввода-вывода извлекает пакеты сообщений из очереди в буфер и выполняет команды записи.
В качестве альтернативы, вы можете добавить поле в ваши сообщения, чтобы указать, какой работник отправил команду записи, и, при необходимости, заставить поток ввода-вывода выдавать разные файлы.
Для повышения производительности также интересно взглянуть на асинхронные версии системных примитивов ввода-вывода (чтение / запись), если ваша хост-ОС их поддерживает. Поток ввода-вывода сможет контролировать несколько одновременных операций ввода-вывода и наполнять ОС новыми, как только завершится один.
Как было указано в комментариях, вам придется следить за потоком ввода-вывода на предмет перегрузок и соответственно настраивать количество рабочих. «Естественный» механизм, основанный на обратной связи, состоит в том, чтобы просто ограничить очередь, и рабочие будут ждать блокировки, пока на ней не освободится место. Это позволяет вам контролировать количество создаваемых данных в любой точке в течение срока службы процесса, что является важным моментом в сценариях с ограниченным объемом памяти.
Ваш cat
проблемы
Что касается cat
, этот инструмент командной строки просто прочитайте все, что написано на его входной канал (обычно stdin
) и дублирует его на выходе (stdout
). Это так просто, и вы можете ясно увидеть сходство с решением, предложенным выше. Разница в том, что cat
не понимает внутреннюю структуру файла (если есть), он имеет дело только с байтовыми потоками, что означает, что если несколько процессов записывают одновременно в cat
вход без синхронизации, полученный результат, вероятно, будет полностью перепутан. Другая проблема заключается в валентность (или его отсутствие) IO примитивов.
NB. В некоторых системах есть небольшая небольшая функция, которая называется вилка, что позволяет вам иметь несколько «независимых» потоков данных, мультиплексированных в одном файле. Если вам доведется работать на платформе, поддерживающей эту функцию, все ваши потоки данных могут быть объединены в один файл, но доступны по отдельности.