Как я могу синхронизировать два процесса доступа к файлу на NAS? - PullRequest
4 голосов
/ 23 января 2009

Вот в чем дело: у меня есть два приложения, написанные на C ++ и работающие на двух машинах с разными ОС (одна Linux и одна Windows). Один из этих процессов отвечает за обновление XML-файла на NAS (Network Attached Storage), в то время как другой читает этот файл.

Можно ли синхронизировать эти два процесса, чтобы избежать чтения файла во время его изменения?

Ответы [ 5 ]

8 голосов
/ 23 января 2009

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

Редактировать : Чтобы обратиться к комментариям, вы можете реализовать двойную проверку шаблона типа блокировки. И у читателя, и у писателя есть файл блокировки и двойная проверка перед началом работы, например:

Считыватель: Проверьте файл блокировки записи, создайте файл блокировки чтения, проверьте файл блокировки записи, если существует, удалите файл чтения и отмените его.

Writer: Проверьте файл блокировки чтения, создайте файл блокировки записи, проверьте файл блокировки чтения, если существует, удалите файл блокировки записи и отмените.

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

5 голосов
/ 26 января 2009

Спасибо всем за ваши ответы.

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

2 голосов
/ 23 января 2009

ОК, вам нужен механизм блокировки для контроля доступа.

Большинство * nix файловых систем обеспечивают это. Я подозреваю, что он также доступен в файловой системе Windows (так как этот механизм используется в Perl), но может иметь другое имя.

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

flock () предоставляет как общие блокировки (или READ Lock), так и эксклюзивные блокировки (или WRITE Lock). flock будет блокировать ваш поток (не занятым способом), пока файл не будет разблокирован пользователем (он также предоставляет НЕ блокирующие проверки, чтобы вы могли делать другие вещи во время ожидания).

Ознакомьтесь с паствой в разделе 2 справочных страниц.

int     flock(int fd, int operation);

Flock() applies or removes an advisory lock on the file associated with the file
descriptor fd.  A lock is applied by specifying an operation parameter that is
one of LOCK_SH or LOCK_EX with the optional addition of LOCK_NB.  To unlock an
existing lock operation should be LOCK_UN.
1 голос
/ 23 января 2009

Можно ли переключаться с файлов на базу данных?

Этот тип параллелизма очень хорошо управляется СУБД. Он не должен быть дорогим или сложным в установке. MySql, Postgress или JavaDB справятся с этим элегантно, за небольшую плату или бесплатно.

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

1 голос
/ 23 января 2009

Если файлы находятся на общем ресурсе NFS, вы можете использовать fcntl (2) для блокировки файла. Проверьте вопрос D10 в Linux NFS FAQ . У меня очень мало опыта работы с Windows API, но из того, что я слышал, у них хорошая поддержка POSIX, поэтому вы сможете использовать fcntl, если они поддерживают POSIX.1-2001.

Если вы обращаетесь к файлам по разным протоколам (например, AFS или SMB), возможно, вы могли бы настроить простой сервер синхронизации, который управляет блокировками через интерфейс IPC?

...