Потокобезопасная многофайловая запись - PullRequest
3 голосов
/ 15 февраля 2011

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

Другие вопросы предлагали использовать мьютексы, но я не совсем понимаю, как мьютекс может помочь в этом сценарии - список файлов динамический и известен только потоку.

Было бы целесообразно использовать блокировку файлов в этом случае? Если это так, как можно реализовать блокировку файлов в поточно-ориентированном режиме?

Ответы [ 3 ]

2 голосов
/ 15 февраля 2011

flock будет работать нормально.Он не блокирует дескрипторы файлов, он блокирует реальный файл.

Файл, который был исключительно flock ', не может быть снова заблокирован исключительно другим процессом или потоком.Это победило бы всю цель замков.

Одно замечание, что эти замки носят рекомендательный характер.Процесс, который не использует flock, может успешно перезаписать файл, даже если другой процесс имеет эксклюзивный - flock 'его.

1 голос
/ 15 февраля 2011

Я не могу сказать, что это было бы "оптимальным" решением, но я бы предложил что-то вроде этого:

Поддерживать связанный список структуры, которая содержит две вещи:

  1. Имя файла
  2. Переменная ожидания состояния, связанная с файлом.

Поток A. Когда демон получает запрос, мьютекс блокирует список и проверяет, находится ли имя файла в списке или нет.Если это не так, добавьте новую запись в связанный список с новой переменной условия ожидания для использования другими потоками.Отпустите блокировку мьютекса.Выполните файловую операцию.После завершения заблокируйте связанный список и удалите запись структуры для этого файла, а затем сообщите другим потокам через объект ожидания.

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

1 голос
/ 15 февраля 2011

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

Если файл не может быть записан,решить, что вы хотите сделать ... в противном случае сообщить об успехе.

Несколько слушателей, одна центральная коллекция блокировки файлов, несколько писателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...