Мне трудно обдумать это.
В моей тестовой настройке есть сценарий оболочки, который непрерывно вызывает ls -la для файла 1G и распечатывает время с момента последнего запуска. Затем я запускаю программу, чтобы изменить части файла и синхронизировать его с диском.
Не имеет значения, вызываю ли я fsync, или система выполняет синхронизацию, или даже если я использую pwrite для записи различных частей (все еще проверяя этот бит), когда произойдет синхронизация, 'ls -la' остановится для всего время синхронизации - между 7-40 секундами (в зависимости от редкости модификаций).
Если я использую msync для синхронизации порций или пытаюсь выполнять fsync чаще, когда пишу, длительность становится намного больше (может быть, в 10 раз больше, но даже больше, в зависимости от того, как часто я это делаю). Приведенный выше msync записывает только 16 КБ / транзакцию, даже если страницы являются последовательными.
Я где-то читал, что OpenBSD реализовал «частичную запись в файл» или что-то в этом роде. Я не могу сейчас вспомнить.
Есть ли в любом случае, я могу сделать что-то подобное с эффективностью fsync без блокировки файла на все время?
На самом деле, проблема «А» (для которой я думаю, что «В» - это решение) состоит в том, чтобы просто работать с большими файлами и «поощрять» их записывать на диск, чтобы можно было быстро освободить память, если это необходимо. быть. Простое игнорирование NO_SYNC не годится, так как изменения произойдут примерно в одно и то же время, вызывая эту ситуацию. Кажется, что ни один из других вариантов Madvise не поможет. То есть, если я не синхронизируюсь, то страницы, кажется, застревают, пока у меня не кончится память, где они внезапно начнут обмениваться (хотя только при 16 КБ / транзакции и очень низких МБ / с).
Как же вы работаете с большими файлами во FreeBSD?
РЕШЕНИЕ:
Я обнаружил, что, настраивая свои блоки msync и используя MS_ASYNC вместо MS_SYNC в вызове msync, я могу добиться желаемой производительности, в то же время позволяя другим процессам открывать и mmap/ читать файл.