эксклюзивный файл блокировки на веб-сервере Windows c

Я пишу (очень маленький) веб-сервер на языке C в Windows. Мне нужен эксклюзивный файл блокировки как для чтения, так и для записи файлов, я прочитал документацию msdn о блокировке и т. д., и я нашел функцию LockFileEx со структурой OVERLAPPED и Event hEvent, я также читал о том, как они работают, но вопрос в следующем: - На веб-сервере у нас есть много файлов, когда поток блокирует, например, файл "test.txt" (эксклюзивная блокировка), потому что был запрос этого файла, как я могу синхронизировать другой поток, который хочет получить блокировку в том же файле?

благодарю вас.


person user2199646    schedule 22.03.2013    source источник
comment
используйте блокировку, чтобы синхронизировать ваш запрос с файлом вместо блокировки файла   -  person xjdrew    schedule 22.03.2013


Ответы (1)


Взгляните на использование объектов мьютекса. Они должны решить эту проблему для вас.

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

person K Scott Piel    schedule 22.03.2013
comment
хорошо, но таким образом мне нужен мьютекс для каждого файла, который потоки хотят открыть? И если это так, значит, мне нужно хранить все мьютексы в памяти? Правильно? - person user2199646; 22.03.2013
comment
Ну... во-первых, вам не нужна блокировка, если только файл не доступен для записи или не подлежит изменению, пока сервер читает его для доставки клиенту. В противном случае нет причин запрашивать блокировки файла, доступного только для чтения. Тем не менее, да и нет ... это будет зависеть от приложения. Вы можете использовать мьютекс для каждого каталога, для каждой службы или любое количество других оптимизаций, но это определяется дизайном и приложением. - person K Scott Piel; 22.03.2013
comment
да, проблема в том, что для конкретных файлов требуется эксклюзивный доступ на чтение/запись. - person user2199646; 22.03.2013
comment
Хорошо... это прямое приложение C или приложение C++? Если вы используете C++, я бы предложил использовать контейнер STL::map для управления мьютексами... ключ в имени файла, значение которого является мьютексом. В противном случае используйте аналогичную конструкцию C или контейнерную библиотеку. - person K Scott Piel; 22.03.2013
comment
это прямое консольное приложение C - person user2199646; 22.03.2013
comment
Настройте связанный список запрашиваемых файлов, содержащий имя файла и мьютекс. Если файл есть в списке, заблокируйте мьютекс для этого файла, если его нет в списке, создайте мьютекс и добавьте его в список. Если последний запрашивающий выпустил файл, удалите его из списка. - person K Scott Piel; 22.03.2013
comment
хорошо, я попытался реализовать список ссылок, но теперь у меня проблема... как я могу узнать, является ли поток последним, кто запросил мьютекс? - person user2199646; 24.03.2013
comment
Потому что в списке ссылок больше не будет записей. Это будет последний узел на этом. Или, точнее, listEntry-›next будет NULL. - person K Scott Piel; 24.03.2013
comment
хорошо .. вопрос был: как я могу узнать, является ли поток последним, который запросил мьютекс для file1.txt (например)? меня беспокоит то, что происходит в этом сценарии: есть поток A, который первым получает мьютекс1 для файла file1.txt. Теперь поток B также хочет получить файл file1.txt, поэтому он просматривает список и находит этот файл. Теперь поток B блокируется на mutex1 (WaitForSingleObject). Если поток A закончил свою работу и сейчас, как поток A узнает, что есть поток B, ожидающий мьютекса? Возможно, я не понял структуру, которую вы сказали. благодарю вас - person user2199646; 25.03.2013
comment
Структура представляет собой список файлов, которые система запрашивает для загрузки, и мьютекс для каждого запрошенного файла. Сама система блокировки мьютекса может беспокоиться о том, кто получит файл следующим. Вы можете сказать, что вы последний запрашивающий, если нет ожидающих блокировок. Но вы действительно не должны обязаны удалять его из списка, вы можете просто оставить его, если скоро появится новый запросчик. - person K Scott Piel; 25.03.2013
comment
я беспокоюсь о состоянии гонки: если поток A закончит, как он узнает, что в файле 1.txt нет ожидающих запросов? если узел списка будет удален, как насчет ожидающих потоков? а если придет другой нить который претендует на этот же файл? он не мог видеть, что его ждут другие потоки... поэтому он создаст новый узел в связанном списке, и результат непредсказуем... верно? - person user2199646; 25.03.2013
comment
Существует исключительная ситуация, когда поток запрашивает блокировку между моментами, когда текущий поток проверяет наличие ожидающего запроса и удаляет запись из списка. Если вы не боитесь, что список будет расти без границ, просто оставьте его. Создайте запись по первому запросу и оставьте ее до выхода из приложения. Однако вы можете рассмотреть возможность использования поиска по хешу, если список станет большим, иначе по мере роста списка производительность снизится. - person K Scott Piel; 25.03.2013