Блокировка файла с твист
Как и другие ответы уже упоминалось, самый простой способ создать файл блокировки в том же каталоге, что и файл данных.
Поскольку вы хотите иметь доступ к одному файлу на нескольких ПК, лучшим решением, о котором я могу думать, является просто указать идентификатор машины, которая в настоящее время записывается в файл данных.
Таким образом, последовательность записи в файл данных будет:
Проверьте, есть ли блокировка файла присутствует
Если есть файл блокировки, видеть, если я один владея им, проверяя, что его содержимое имеет мой идентификатор.
Если это так, просто напишите в файл данных, затем удалите файл блокировки.
Если это не так, просто подождите секунду или небольшой случайный промежуток времени и повторите весь цикл.
Если файл блокировки не создан, создайте его с моим идентификатором и повторите весь цикл, чтобы избежать условия гонки (перепроверьте, что файл блокировки действительно мой).
Наряду с идентификатором я записывал временную метку в файле блокировки и проверял, является ли она старше заданного значения таймаута.
Если временная метка слишком старая, предположим, что файл блокировки устарел и просто удаляет его, так как может произойти сбой одной из записей ПК в файл данных или может быть потеряно его соединение.
Другое решение
Если вы контролируете формат файла данных, может быть заказать структуру в начале файла для записи ли она заперта или нет.
Если вы просто зарезервируете байт для этой цели, вы можете предположить, например, что 00
будет означать, что файл данных не заблокирован и что другие значения будут представлять собой идентификатор машины, которая в настоящее время записывается на него.
Проблемы с NFS
ОК, я добавил несколько вещей, потому что Иржи Klouda правильно указал, что NFS uses client-side caching, что приведет к фактическому файлу блокировки, находясь в неопределенном состоянии.
несколько способов решить эту проблему:
смонтировать каталог NFS с noac
или sync
вариантов. Это легко, но не полностью гарантирует согласованность данных между клиентом и сервером, хотя все равно могут возникать проблемы, хотя в вашем случае это может быть хорошо.
Открыть файл блокировки или файл данных, используя атрибуты O_DIRECT
, O_SYNC
или O_DSYNC
. Это должно полностью отключить кеширование.
Это снижает производительность, но обеспечивает согласованность.
Вы может быть в состоянии использовать flock()
заблокировать файл данных, но его реализация пятнистая и вам нужно будет проверить, если ваша конкретная ОС на самом деле использует запирающий службу NFS. В противном случае он ничего не может сделать.
Если файл данных заблокирован, то другой клиент, открывающий его для записи, потерпит неудачу.
О да, и, похоже, он не работает на акциях SMB, поэтому, наверное, лучше всего просто забыть об этом.
Не используйте NFS и вместо этого используйте Samba: есть good article on the subject и почему NFS, вероятно, не лучший ответ на ваш сценарий использования.
В этой статье вы также найдете различные способы блокировки файлов.
Решение Jiri также является хорошим.
В принципе, если вы хотите, чтобы все было просто, не используйте NFS для часто обновляемых файлов, которые совместно используются несколькими компьютерами.
Что-то другое
Используйте небольшой сервер базы данных, чтобы сохранить ваши данные в и обойти проблемы блокировки NFS/SMB в целом или сохранить текущую систему с множеством файлов данных и просто написать небольшую утилиту для объединения результатов.
Это может быть самое безопасное и простое решение вашей проблемы.
Вы, должно быть, пропустили ту часть, где он сказал, что ему нужна синхронизация между разными компьютерами. –
И это решение не будет работать над NFS по его просьбе. –
Почему бы не работать? Я не хочу писать файл локально на каждом компьютере, но в одном месте для всех. – Seb