Как реализовать безопасность потоков для древовидной структуры, используемой для следующего сценария? - PullRequest
0 голосов
/ 11 октября 2011

Я использую код C #, расположенный по следующим ссылкам, для реализации проекта Ram-disk.

В качестве резюме,код, указанный выше, использует простую древовидную структуру для хранения каталогов, подкаталогов и файлов.В корне находится объект MemoryFolder, в котором хранится ноль или более объектов 'MemoryFolder' и / или MemoryFile объектов.Каждый объект MemoryFolder, в свою очередь, хранит ноль или более MemoryFolder объектов и / или MemoryFile объектов и т. Д. До неограниченной глубины.

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

  1. Одновременное создание двух разных папок (каждая в отдельном потоке) в одной и той же родительской папке может происходить одновременно, если это позволяет потоково-безопасная реализация.В противном случае должна быть реализована некоторая стратегия блокировки, чтобы разрешить только последовательное создание.

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

  3. Что касается каждого уникального файла, обеспечивает одновременный доступ длянесколько потоков ReadFile, но с ограничением доступа к одному потоку WriteFile.

  4. Если два отдельных потока ReadFile (запущены почти одновременно), каждый из другого приложения пытается создатьПапка с тем же именем (при условии, что папка еще не существует до того, как запущены оба потока), первый поток, который входит в Ram-Disk, всегда успешно выполняется, а второй - всегда отказывает.Другими словами, порядок выполнения потоков является детерминированным.

  5. Метод вычисления общего дискового пространства GetDiskFreeSpace, работающий в отдельном потоке, не должен завершать свое выполнение, пока все WriteFile потоков, которыеуже находятся в процессе завершения его выполнения.Все последующие потоки WriteFile, которые не начали выполняться, блокируются до тех пор, пока поток GetDiskFreeSpace не завершит свое выполнение.

1 Ответ

0 голосов
/ 11 октября 2011

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

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

Возможно, существует способ сделать эту структуру данных блокированной.свободно.Однако сделать это может быть довольно сложно.Блокировка чтения / записи даст вам необходимую функциональность, и я подозреваю, что она будет достаточно быстрой.

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

...