Оптимальный метод блокировки файла

В Windows есть возможность открыть файл с эксклюзивными правами доступа. Unix не делаетт.

Чтобы обеспечить эксклюзивный доступ к какому-либо файлу или устройству, в Unix принято использовать файл блокировки, обычно хранящийся в каталоге / var / lock.

Инструкция Copen( "/var/lock/myLock.lock", O_RDWR | O_CREAT | O_EXCL, 0666 ) возвращает -1, если файл блокировки уже существует, в противном случае он его создает. Функция является атомарной и гарантирует отсутствие гонки.

Когда ресурс освобождается, файл блокировки удаляется с помощью следующей инструкции.remove( "/var/lock/myLock.lock" )

Есть две проблемы с этим методом.

Программа может завершиться без снятия блокировки. Например, потому что он убит, падает или что-то еще. Файл блокировки остается на месте и будет препятствовать любому доступу к ресурсу, даже если он больше не используется.

Файл блокировки создается с правами на групповую и мировую запись, но обычной практикой является настройка учетных записей для использования маски разрешений, которая удаляет права на групповую и мировую запись. Таким образом, если бы у нас был надежный метод для определения того, что блокировка является бесхозной (не используется), пользователь, не являющийся владельцем файла, не сможет удалить его.

Для записи я использую файл блокировки, чтобы обеспечить эксклюзивный доступ к устройству, подключенному к последовательному порту (на самом деле / dev / ttyUSBx). Консультативный метод, требующий сотрудничества, в порядке. Но между разными пользователями должен быть обеспечен эксклюзивный доступ.

Есть ли лучший способ синхронизации, чем файл блокировки? Как определить, запущен ли еще процесс, создавший файл блокировки? Как сделать так, чтобы другой пользователь мог удалить файл блокировки, если он не используется?

Одним из решений, которое я придумал, было использование файла в качестве файла сокета Unix. Если файл существует, попробуйте подключиться, используя файл. Если это не удается, мы можем предположить, что процесс владельца файла мертв. Для этого требуется иметь зацикливание потока на сокетеaccept() в процессе владельца. К сожалению, система нене быть атомным больше.

Ответы на вопрос(6)

Ваш ответ на вопрос