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

строки? а если я пишу одним куском, а не построчно? =) то ваще данные перепутаются?
проверь - это не кошерно, я хочу узнать, как ОС должна действовать в этом случае.
думаю, что да
файл - это же не бд
файл - это же не бд
фиг знает, как в линуксе, но в винде по умолчанию два приложения в один файл писать не могут (черт, буквально час назад выяснилось, что из-за этого и одной дурацкой опечатки пропал результат двухдневных вычислений
)
Однако могут, если задать при открытии файла соотв-ые параметры.
Логично, если в Линуксе то же самое. Потому что это разумно.
)Однако могут, если задать при открытии файла соотв-ые параметры.
Логично, если в Линуксе то же самое. Потому что это разумно.
строки не будут, потому что в файл (и в Линуксе в том числе) пишется по умолчанию не строками, а буферами.
По идее, когда одна программа открыла файл на запись, вторую пошлют подальше с такой просьбой.
В зависимости от конкретной ситуации, либо попытка второй программы открыть этот файл завершится неудачей, либо файл откроется - но только тогда, когда его закроет первая программа.
В зависимости от конкретной ситуации, либо попытка второй программы открыть этот файл завершится неудачей, либо файл откроется - но только тогда, когда его закроет первая программа.
Логи не так пишут. Для них придуман O_APPEND.
Семантика работы с файлами должна быть описана у Стивенса (FAQ соседнего раздела).
Семантика работы с файлами должна быть описана у Стивенса (FAQ соседнего раздела).
> из-за этого и одной дурацкой опечатки пропал результат двухдневных вычислений
---
"Аллах не ведёт людей неверных."
set -C
---
"Аллах не ведёт людей неверных."
> понять, как будут записаны логи
Логи надо писать предназначенными для этого средствами.
Например, через syslog или daemontools.
---
"Аллах не ведёт людей неверных."
Логи надо писать предназначенными для этого средствами.
Например, через syslog или daemontools.
---
"Аллах не ведёт людей неверных."
Ну это не совсем лог. Это статистика работы многоэкземплярного приложения, собираемая во время работы и скидываемая в файл при закрытии программы.
Может, проще запереть файл и не пудрить мозг разгребанием
всей этой байды?
---
...Я работаю антинаучным аферистом...
всей этой байды?
---
...Я работаю антинаучным аферистом...
Не проще, так как возможно, что файл будет находиться на NFS или AFS, и приложение об этом знать ничего не будет...
Ок, а если я открываю файл в режиме append?
Ок, а если я открываю файл в режиме append?
так как возможно, что файл будет находиться на NFS или AFSЯ бы не стал прикасаться к этой проблеме и двенадцатифутовой палкой. То, о чём ты спрашиваешь в начале треда это advisory file locking. Попробуй погугли по этим словам - будет достаточно информации, начиная от flock(2) и заканчивая книгами на эту тему.
То, как работает advisory file locking на NFS зависит от версии протокола NFS, и от реализации серверной и клиентской стороны. В итоге получается масса комбинаций, и большинство из них не работают. Сейчас тут конечно высунется jesus и скажет, что клиент-солярис и сервер-солярис работают. Правда он не сможет уточнить тонкости того как работает NFSv2 или NFSv3 в этом случае.
Короче, я на твоём месте стал думать бы о том, как решить твою задачу по-другому, так чтобы не полагаться на file locking по NFS. Либо придётся чётко придерживаться рабочей комбинации NFS-клиента и NFS-сервера.
А про AFS ничего не могу сказать, как там решена задача file locking через сеть.
> Не проще, так как возможно, что файл будет находиться на NFS
> или AFS, и приложение об этом знать ничего не будет...
Я бы сказал, что тогда лучше заняться подысканием более
понятного протокола, чем NFS и файловая система вообще.
---
...Я работаю антинаучным аферистом...
> или AFS, и приложение об этом знать ничего не будет...
Я бы сказал, что тогда лучше заняться подысканием более
понятного протокола, чем NFS и файловая система вообще.
---
...Я работаю антинаучным аферистом...
Блин, как всё плохо. Ну а вариант с filename.lock тут не покатит?
так и делают, но там тоже-это как-то извратно делается для надёжности,
да и с производительностью будут косяки конечно, если поток большой.
не лучше ли поискать готовые решения для сбора логов по сети чем городить свою хрень?
да и с производительностью будут косяки конечно, если поток большой.
не лучше ли поискать готовые решения для сбора логов по сети чем городить свою хрень?
Это не лог.
Производительность решения не важна, так как прога пишет в файл один раз в конце своей работы, и некритично, сколько времени она это будет делать.
Короче, обрисовываю ситуацию: это приложение голосового сервиса. Оно поднимается по звонку, отрабатывает голосовую задачу, а когда пользователь кладёт трубку, она флашит собранную статистику активности пользователя в общий файл статистики. Статистика пишется в своём собственном формате, так что стандартные решения не очень подходят.
Производительность решения не важна, так как прога пишет в файл один раз в конце своей работы, и некритично, сколько времени она это будет делать.
Короче, обрисовываю ситуацию: это приложение голосового сервиса. Оно поднимается по звонку, отрабатывает голосовую задачу, а когда пользователь кладёт трубку, она флашит собранную статистику активности пользователя в общий файл статистики. Статистика пишется в своём собственном формате, так что стандартные решения не очень подходят.
такому приложению нельзя разрешать работать с сетевой ФС
с локальной - можно, если файл открывается с O_APPEND, и нет косяков с буферизацией в stdio
с локальной - можно, если файл открывается с O_APPEND, и нет косяков с буферизацией в stdio
Короче, обрисовываю ситуацию: это приложение голосового сервиса. Оно поднимается по звонку, отрабатывает голосовую задачу, а когда пользователь кладёт трубку, она флашит собранную статистику активности пользователя в общий файл статистики.RADIUS
Статистика пишется в своём собственном формате, так что стандартные решения не очень подходят.В RADIUS есть такая штуковина - vendor specific attribute.
Можно заблокировать часть файла или весь файл целиком
Если файл fdesc уже заблокирован, то функция
fcntl(fdesc,F_SETLKW,&dls)
приведет к приостановке программы. В этом случае ожидание процесса внутри fcntl будет прервано после снятия блокировки другой программой или по сигналу.
#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 будет прервано после снятия блокировки другой программой или по сигналу.
К моему огромному сожалению, программа написана не на C, а на PHP.
> fcntl
Ага, только как это будет на NFS работать?
Ага, только как это будет на NFS работать?
> К моему огромному сожалению, программа написана не на C, а на PHP.
О боже, PHP уже проникло в такие ответственные области как ведение логов billable данных
О боже, PHP уже проникло в такие ответственные области как ведение логов billable данных

К моему огромному сожалению, программа написана не на C, а на PHP.Из PHP какой-нибудь веб-сервис вроде проще вызвать, чем правильно в файл записать. Вот что-нибудь вроде этого и надо использовать.
Хотя fcntl тоже есть.
Для этого имеется сервис nfslock
Вообще не понятно, зачем всё писать в один файл, если можно в разные. Так надёжнее, проще потом обрабатывать, нет сложностей при ротации.
PHP используется как наиболее дешёвый с точки зрения разработки скриптовый язык для управления движком, который в свою очередь, конечно же, написан на C.
На основании логов и статистики, сохраняемых скриптами на PHP, никаких действий, связанных со счислением/начислением денежных средств, не производится. Так что всё не так плохо, как кажется.
На основании логов и статистики, сохраняемых скриптами на PHP, никаких действий, связанных со счислением/начислением денежных средств, не производится. Так что всё не так плохо, как кажется.
О боже, PHP уже проникло в такие ответственные области как ведение логов billable данныхЕсли можно в PHP вводить логин/пароль/пин, то можно оттуда и логи писать.
Вообще не понятно, зачем всё писать в один файл, если можно в разные. Так надёжнее, проще потом обрабатывать, нет сложностей при ротации.+1
Пусть каждый пишет в специальную директорию файлик типа log-hostname-pid, а там специально обученный скрипт весь мусор, который находит, сваливает в общий файл.
Или, опять же, взять и проверить. В UFS, например, фокус "тупо открыл-написал-закрыл" срабатывает и данные от нескольких форок не перемешиваются. Может, в твоей FS так же получится?
> Или, опять же, взять и проверить.
Лучше всё-таки почитать спецификации.
А тем, кто не понимает, зачем, сначала учебник.
Лучше всё-таки почитать спецификации.
А тем, кто не понимает, зачем, сначала учебник.
Так на php есть довольной несложный способ сливать все в БД, хочешь в MySQL, хочешь в PostgreSQL, да много там всяких разных.
Мало того, что не надо гемороиться с locking-ом, так потом еще будет довольно удобно все обрабатывать.
Мало того, что не надо гемороиться с locking-ом, так потом еще будет довольно удобно все обрабатывать.
Оставить комментарий
Fragaria
Народ, подскажите, что произойдёт в такой ситуации: два приложения более-менее одновременно открывают один файл и пишут в него объём данных порядка сотни строк (в сумме килобайт 10) одним fwrite. Как будут располагаться данные в файле, когда обе программы закроют файл? И вообще, даст ли ОС второму приложению открыть для записи файл, уже открытый первым приложением? Мне это нужно для того, чтобы понять, как будут записаны логи работы двух экземпляров одного приложения.