Файл блокировки с поворотом
Как и в других ответах, самый простой способ - создать файл блокировки в том же каталоге, что и файл данных.
Поскольку вы хотите иметь доступ к одному и тому же файлу через несколько ПК, лучшее решение, о котором я могу подумать, - это просто включить идентификатор машины, которая в данный момент записывает данные в файл данных.
Таким образом, последовательность записи в файл данных будет:
Проверить наличие файла блокировки
Если есть файл блокировки, посмотрите, владею ли я им, проверив, что его содержимое имеет мой идентификатор.
Если это так, просто запишите файл данных и удалите файл блокировки.
Если это не так, просто подождите секунду или небольшую случайную промежуток времени и попробуйте снова весь цикл.
Если файл блокировки отсутствует, создайте его с моим идентификатором и повторите весь цикл, чтобы избежать состояния гонки (еще раз проверьте, что файл блокировки действительно мой).
Наряду с идентификатором я бы записал метку времени в файл блокировки и проверил, старше ли он заданного значения времени ожидания.
Если временная метка слишком старая, то предположим, что файл блокировки устарел, и просто удалите его, так как это может означать, что один из ПК, выполняющий запись в файл данных, мог быть поврежден или его соединение могло быть потеряно.
Другое решение
Если вы контролируете формат файла данных, может быть зарезервировать структуру в начале файла для записи, заблокирован он или нет.
Если вы просто зарезервируете байт для этой цели, вы можете предположить, например, что 00
будет означать, что файл данных не заблокирован, и что другие значения будут представлять идентификатор машины, в данный момент выполняющей запись в него.
Проблемы с NFS
Хорошо, я добавляю несколько вещей, потому что Джири Клоуда правильно указал, что NFS использует кэширование на стороне клиента , что приведет к тому, что фактический файл блокировки будет находиться в неопределенном состоянии.
Несколько способов решить эту проблему:
смонтировать каталог NFS с опциями noac
или sync
. Это просто, но не полностью гарантирует согласованность данных между клиентом и сервером, хотя, тем не менее, могут возникнуть проблемы, хотя в вашем случае все может быть в порядке.
Откройте файл блокировки или файл данных, используя атрибуты O_DIRECT
, O_SYNC
или O_DSYNC
. Предполагается, что это вообще отключит кеширование.
Это снизит производительность, но обеспечит согласованность.
Вы можете иметь возможность использовать flock()
для блокировки файла данных, но его реализация нестабильна, и вам нужно будет проверить, действительно ли ваша конкретная ОС использует службу блокировки NFS. В противном случае он может вообще ничего не делать.
Если файл данных заблокирован, другой клиент, открывающий его для записи, не сможет.
О да, и похоже, что это не работает с акциями SMB, так что, вероятно, лучше просто забыть об этом.
Не используйте NFS и просто используйте Samba: есть хорошая статья на эту тему и почему NFS, вероятно, не лучший ответ на ваш сценарий использования.
В этой статье вы также найдете различные способы блокировки файлов.
Решение Джири тоже хорошее.
По сути, если вы хотите сохранить простоту, не используйте NFS для часто обновляемых файлов, которые используются несколькими компьютерами.
Что-то другое
Используйте небольшой сервер базы данных, чтобы сохранить свои данные и вообще обойти проблемы с блокировкой NFS / SMB, или сохранить свою текущую систему с несколькими файлами данных и просто написать небольшую утилиту для объединения результатов.
Это может быть самым безопасным и простым решением вашей проблемы.