Запись большого количества файлов из долго работающего процесса?

У меня есть проект, который сканирует большой файл (2,5 ГБ), выбирая строки, которые затем будут записаны в некоторое подмножество из нескольких сотен файлов.

Было бы быстрее всего использовать обычные записи с буферизацией, но

  1. Я беспокоюсь о том, что закончатся дескрипторы файлов.
  2. Я хочу иметь возможность наблюдать за ходом файлов во время их записи.
  3. Я бы предпочел как можно меньше потерь, если процесс будет прерван. Неполные файлы все еще частично полезны.

Поэтому вместо этого я открываю в режиме чтения/записи, добавляю новую строку и снова закрываю.

Большую часть времени это было достаточно быстро, но я обнаружил, что в некоторых ОС такое поведение является серьезной пессимизацией. В прошлый раз, когда я запускал его на своем нетбуке с Windows 7, я прервал его через несколько дней!

Я могу реализовать какой-нибудь менеджер файловых дескрипторов MRU, который держит так много файлов открытыми и каждый из них сбрасывает после стольких операций записи. Но разве это перебор?

Должно быть, это обычная ситуация. Есть ли "лучшая практика", "шаблон"?

Текущая реализация написана на Perl и работает на Linux, Solaris и Windows, от нетбуков до phat-серверов. Но меня интересует общая проблема: независимая от языка и кроссплатформенная. Я думаю написать следующую версию на C или node.js.


person hippietrail    schedule 06.09.2012    source источник
comment
как вы читаете файл? построчно? сразу? 2,5 не такой уж большой.   -  person DarthVader    schedule 07.09.2012
comment
Я читал запись за записью, но все сводится к строке за строкой. Кажется, это не размер ввода, который замедляет его почти так же сильно, как все сбросы выходов, которые я думаю.   -  person hippietrail    schedule 07.09.2012
comment
Самый похожий вопрос, который мне удалось найти до сих пор: Открытие и запись к нескольким файлам в C   -  person hippietrail    schedule 07.09.2012


Ответы (1)


В Linux вы можете открыть много файлов (тысячи). Вы можете ограничить количество открытых дескрипторов в одном процессе с помощью системного вызова setrlimit и < встроенная оболочка href="http://ss64.com/bash/ulimit.html" rel="nofollow">ulimit. Вы можете запросить их с помощью системного вызова getrlimit, а также с помощью /proc/self/limits (или /proc/1234/limits для процесса pid 1234). Максимальное количество общесистемных открытых файлов - через /proc/sys/fs/file-max (в моей системе 1623114).

Так что в Linux можно было не заморачиваться и открывать сразу много файлов.

И я бы посоветовал поддерживать запоминания кешировать открытые файлы и использовать их, если это возможно (в политике MRU). Не открывайте и не закрывайте каждый файл слишком часто, только когда достигнут какой-то предел... (например, когда open не удалось).

Другими словами, вы можете иметь свою собственную файловую абстракцию (или просто struct), которая знает имя файла, может иметь открытый FILE* (или нулевой указатель) и сохранять текущее смещение, возможно, также время последнего открытия или записи, затем управлять набором таких вещей в дисциплине FIFO (для тех, у кого открыта FILE*). Вы, конечно, хотите избежать слишком частого close-а (а позже и повторногоopen-инга) файлового дескриптора.

Вы можете время от времени (т.е. раз в несколько минут) вызывать sync(2), но не вызывайте его слишком часто (конечно, не чаще одного раза в 10 секунд). При использовании буферизованных FILE не забывайте иногда fflush их. Опять же, не делайте этого слишком часто.

person Basile Starynkevitch    schedule 06.09.2012
comment
Будет ли проблемой в Linux то, как я открываю, добавляю, сбрасываю и закрываю файлы миллионы раз? Кажется, я помню, как читал, что недавняя оптимизация в Linux сделала это плохо, я думаю, это было связано с тем, как Firefox записывает некоторые типы файлов, которые он использует, с постоянными сбросами, такими как мой. - person hippietrail; 07.09.2012
comment
Я не знаком с концепцией мемоизированного кэша - это то, что я могу легко реализовать на разных платформах (Solaris и Windows - другие среды). Для языка программирования я также открыт. - person hippietrail; 07.09.2012
comment
Я только что добавил ссылки на википедию по мемоизации и кэшированию. - person Basile Starynkevitch; 07.09.2012