[Linux] Одновременная запись в файл двумя приложениями

Fragaria

Народ, подскажите, что произойдёт в такой ситуации: два приложения более-менее одновременно открывают один файл и пишут в него объём данных порядка сотни строк (в сумме килобайт 10) одним fwrite. Как будут располагаться данные в файле, когда обе программы закроют файл? И вообще, даст ли ОС второму приложению открыть для записи файл, уже открытый первым приложением? Мне это нужно для того, чтобы понять, как будут записаны логи работы двух экземпляров одного приложения.

krishtaf

скорее всего в файле строки будут перемешаны.
возьми да проверь, хуле

Fragaria

строки? а если я пишу одним куском, а не построчно? =) то ваще данные перепутаются?

Fragaria

проверь - это не кошерно, я хочу узнать, как ОС должна действовать в этом случае.

krishtaf

думаю, что да
файл - это же не бд

Nastasya483

фиг знает, как в линуксе, но в винде по умолчанию два приложения в один файл писать не могут (черт, буквально час назад выяснилось, что из-за этого и одной дурацкой опечатки пропал результат двухдневных вычислений )
Однако могут, если задать при открытии файла соотв-ые параметры.
Логично, если в Линуксе то же самое. Потому что это разумно.

Nastasya483

строки не будут, потому что в файл (и в Линуксе в том числе) пишется по умолчанию не строками, а буферами.

kruzer25

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

Marinavo_0507

Логи не так пишут. Для них придуман O_APPEND.
Семантика работы с файлами должна быть описана у Стивенса (FAQ соседнего раздела).

Ivan8209

> из-за этого и одной дурацкой опечатки пропал результат двухдневных вычислений

set -C

---
"Аллах не ведёт людей неверных."

Ivan8209

> понять, как будут записаны логи
Логи надо писать предназначенными для этого средствами.
Например, через syslog или daemontools.
---
"Аллах не ведёт людей неверных."

Fragaria

Ну это не совсем лог. Это статистика работы многоэкземплярного приложения, собираемая во время работы и скидываемая в файл при закрытии программы.

Ivan8209

Может, проще запереть файл и не пудрить мозг разгребанием
всей этой байды?
---
...Я работаю антинаучным аферистом...

Fragaria

Не проще, так как возможно, что файл будет находиться на NFS или AFS, и приложение об этом знать ничего не будет...
Ок, а если я открываю файл в режиме append?

sergey_m

так как возможно, что файл будет находиться на NFS или AFS
Я бы не стал прикасаться к этой проблеме и двенадцатифутовой палкой. То, о чём ты спрашиваешь в начале треда это advisory file locking. Попробуй погугли по этим словам - будет достаточно информации, начиная от flock(2) и заканчивая книгами на эту тему.
То, как работает advisory file locking на NFS зависит от версии протокола NFS, и от реализации серверной и клиентской стороны. В итоге получается масса комбинаций, и большинство из них не работают. Сейчас тут конечно высунется jesus и скажет, что клиент-солярис и сервер-солярис работают. Правда он не сможет уточнить тонкости того как работает NFSv2 или NFSv3 в этом случае.
Короче, я на твоём месте стал думать бы о том, как решить твою задачу по-другому, так чтобы не полагаться на file locking по NFS. Либо придётся чётко придерживаться рабочей комбинации NFS-клиента и NFS-сервера.
А про AFS ничего не могу сказать, как там решена задача file locking через сеть.

Ivan8209

> Не проще, так как возможно, что файл будет находиться на NFS
> или AFS, и приложение об этом знать ничего не будет...
Я бы сказал, что тогда лучше заняться подысканием более
понятного протокола, чем NFS и файловая система вообще.
---
...Я работаю антинаучным аферистом...

Fragaria

Блин, как всё плохо. Ну а вариант с filename.lock тут не покатит?

vall

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

Fragaria

Это не лог.
Производительность решения не важна, так как прога пишет в файл один раз в конце своей работы, и некритично, сколько времени она это будет делать.
Короче, обрисовываю ситуацию: это приложение голосового сервиса. Оно поднимается по звонку, отрабатывает голосовую задачу, а когда пользователь кладёт трубку, она флашит собранную статистику активности пользователя в общий файл статистики. Статистика пишется в своём собственном формате, так что стандартные решения не очень подходят.

Marinavo_0507

такому приложению нельзя разрешать работать с сетевой ФС
с локальной - можно, если файл открывается с O_APPEND, и нет косяков с буферизацией в stdio

sergey_m

Короче, обрисовываю ситуацию: это приложение голосового сервиса. Оно поднимается по звонку, отрабатывает голосовую задачу, а когда пользователь кладёт трубку, она флашит собранную статистику активности пользователя в общий файл статистики.
RADIUS
Статистика пишется в своём собственном формате, так что стандартные решения не очень подходят.
В RADIUS есть такая штуковина - vendor specific attribute.

ryshiy28

Можно заблокировать часть файла или весь файл целиком

#include <unistd.h>
#include <fcntl.h>
struct flock dls;
.....
memset(&dls,'\0',sizeof(dls;
dls.l_type=F_WRLCK;
dls.l_whence=SEEK_SET;
if (fcntl(fdesc,F_SETLKW,&dls) == -1)
fatal("Error");
.....
dls.l_type=F_UNLCK;
fcntl(fdesc,F_SETLK,&dls);

Если файл fdesc уже заблокирован, то функция
fcntl(fdesc,F_SETLKW,&dls)
приведет к приостановке программы. В этом случае ожидание процесса внутри fcntl будет прервано после снятия блокировки другой программой или по сигналу.

Fragaria

К моему огромному сожалению, программа написана не на C, а на PHP.

sergey_m

> fcntl
Ага, только как это будет на NFS работать?

sergey_m

> К моему огромному сожалению, программа написана не на C, а на PHP.
О боже, PHP уже проникло в такие ответственные области как ведение логов billable данных

Marinavo_0507

К моему огромному сожалению, программа написана не на C, а на PHP.
Из PHP какой-нибудь веб-сервис вроде проще вызвать, чем правильно в файл записать. Вот что-нибудь вроде этого и надо использовать.
Хотя fcntl тоже есть.

ryshiy28

Для этого имеется сервис nfslock

Marinavo_0507

Вообще не понятно, зачем всё писать в один файл, если можно в разные. Так надёжнее, проще потом обрабатывать, нет сложностей при ротации.

Fragaria

PHP используется как наиболее дешёвый с точки зрения разработки скриптовый язык для управления движком, который в свою очередь, конечно же, написан на C.
На основании логов и статистики, сохраняемых скриптами на PHP, никаких действий, связанных со счислением/начислением денежных средств, не производится. Так что всё не так плохо, как кажется.

Marinavo_0507

О боже, PHP уже проникло в такие ответственные области как ведение логов billable данных
Если можно в PHP вводить логин/пароль/пин, то можно оттуда и логи писать.

valentin160962

Вообще не понятно, зачем всё писать в один файл, если можно в разные. Так надёжнее, проще потом обрабатывать, нет сложностей при ротации.
+1
Пусть каждый пишет в специальную директорию файлик типа log-hostname-pid, а там специально обученный скрипт весь мусор, который находит, сваливает в общий файл.
Или, опять же, взять и проверить. В UFS, например, фокус "тупо открыл-написал-закрыл" срабатывает и данные от нескольких форок не перемешиваются. Может, в твоей FS так же получится?

Marinavo_0507

> Или, опять же, взять и проверить.
Лучше всё-таки почитать спецификации.
А тем, кто не понимает, зачем, сначала учебник.

Sharp

Так на php есть довольной несложный способ сливать все в БД, хочешь в MySQL, хочешь в PostgreSQL, да много там всяких разных.
Мало того, что не надо гемороиться с locking-ом, так потом еще будет довольно удобно все обрабатывать.
Оставить комментарий
Имя или ник:
Комментарий: