многопоточная блокировка файлов в linux

Я работаю над многопоточным приложением, в котором нескольким потокам может потребоваться эксклюзивный доступ к одному и тому же файлу. Я ищу способ сериализации этих операций. Я планировал использовать блокировку flock, lockf или fcntl. Однако оказывается, что с помощью этих методов попытка заблокировать файл вторым потоком, когда первый поток уже владеет блокировкой, будет разрешена, потому что два потока находятся в одном процессе. Это согласно справочным страницам для flock и fnctl (и Я предполагаю, что в Linux lockf реализован с помощью fnctl). Также поддерживается другим вопросом. Итак, существуют ли другие способы блокировки файла в Linux, которые работают на уровне потока, а не на уровне процесса?

Некоторые альтернативы, которые я придумал, которые мне не нравятся:

1) Используйте файл блокировки (xxx.lock), открытый с помощью O_CREAT | Флаги O_EXCL. Этот вызов будет успешным только в одном потоке, если есть конфликт. Проблема в том, что тогда другие потоки должны вращаться в вызове, пока не достигнут блокировки, а это означает, что я должен _yield() или sleep(), что заставляет меня думать, что это не лучший вариант.

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

Есть ли другие способы сделать это?

Редактировать: я только что обнаружил этот текст на справочных страницах моей системы, которого нет на справочных страницах в Интернете:

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

Мне не нравятся слова «может быть отказано», я бы предпочел «будет отказано», но, думаю, пришло время это проверить.


person cheshirekow    schedule 19.02.2013    source источник
comment
Memcached поддерживает операции с атомарными ключами, вокруг которых можно создавать стратегии распределенной блокировки. :) Я знаю, это может показаться странным, но это прекрасно работает, особенно если у вас есть программы, разбросанные по сети.   -  person Dave S.    schedule 19.02.2013
comment
Конечно из коробки. Я смотрел на memchached раньше, но пока не нашел для него применения. Звучит как кувалда, но я обязательно буду иметь это в виду. Спасибо за предложение.   -  person cheshirekow    schedule 19.02.2013
comment
Нужны ли вам только рекомендательные блокировки или настоящие файловые блокировки (чтобы любому процессу было отказано в доступе к заблокированному файлу)? Если только в качестве рекомендации, вы можете просто использовать pthread_mutex или pthread_mutex в сочетании с блокировками файлов, если вам нужны как межпотоковые, так и межпроцессные.   -  person Yevgeniy P    schedule 11.06.2016
comment
На самом деле комбинация pthread_mutex и блокировок файлов будет работать и с реальными блокировками, при условии, что все потоки в вашем приложении следуют этому протоколу.   -  person Yevgeniy P    schedule 11.06.2016