ВходНаше всё Теги codebook PARTS Поиск Опросы Закон Понедельник
21 июня
/1017270
Топик полностью
fk0 (10.07.2020 19:24, просмотров: 395) ответил MBedder на Я не о том, во что сложить - CSV проходит (пока), а как сложить, чтобы потом можно было восстановить исходный порядок посылок и пакетов
Пишет один процесс или разные? В один файл или в разные? Если файл один (без буферизации, разумеется, и с O_APPEND), то порядок очевиден... можно таймштамп добавить (но он может совпадать у соседних записей). Если процесс один, поток один, есть точка, где всё упорядочивается явно, то там можно порядковый номер записи добавить. 

Если пишут разные процессы, то вариант писать в один файл с O_APPEND (для Win32: FILE_APPEND_DATA, OPEN_ALWAYS и _без_ FILE_WRITE_DATA). И работает оно только для локальных файлов (не сетевых). За раз (один вызов write) нужно записать одну запись целиком, размер записи ограничен чем-то там, условно 4-килобайта максимум, вызывать нужно прямо write (WriteFile) без всяких библиотечных обёрток с буферизацией. Или вместо файла писать так же в пайп (сокет) и на противоположном конце отлавливать записи, добавлять серийный номер и записывать уже из одного процесса в файл.


Преимущества пайпа: в пайп можно писать записями разной длины, записи до определённой длины (порядка 64к) всегда атомарны (не будут перемешаны кусками с записью из другого процесса), чтение из пайпа не ждёт неизвестно сколько, а выходит сразу как очередная записанная (даже короче, чем ожидается) порция доступна. У пайпа может быть много писателей.


С сокетом, подойтёт только datagram (udp) сокет, ибо stream (tcp) подразумевает только одного писателя и одного читателя. Опять же датаграммы доставляются атомарно (лимит размера порядка 64к). Чтение всегда на границах датаграммы (если в пайп много навалили, то потом прочитать можно сразу сотню записей и нужно их разбирать на отдельные как-то руками), поштучно, что удобно. Может работать не только локально, но и через сеть (но потерю датаграмм обнаруживать вручную, что неудобно).


Как вариант тот же SQL -- делать все INSERT'ы (в разные таблицы) от одного источника за одну транзакцию. Если BerkeleyDB -- то не скажу, в теории и на юниксе может, на винде х.з. как вообще. Но транзакция в любой БД -- дорогая. Поэтому лучше вначале сериализовать в один файл, а потом из него вставлять в БД весь файл за одну транзакцию, чем чтоб процессы дрались за доступ к БД. Или сериализовать через пайп в один процесс, который будет работать с БД.

[ZX]
Ответить
Ответы