Мне нужно получить доступ к файлу одновременно с несколькими потоками. Это должно быть сделано одновременно, без сериализации потоков по соображениям производительности.
Файл, в частности, был создан с атрибутом временного файла, который поощряет окна сохранять файл в системном кэше. Это означает, что большую часть времени чтение файла не будет происходить рядом с диском, но будет считывать часть файла из системного кэша.
Возможность одновременного доступа к этому файлу значительно улучшит производительность некоторых алгоритмов в моем коде.
Итак, здесь есть два вопроса:
- Возможно ли для Windows одновременный доступ к одному и тому же файлу из разных потоков?
- Если так, как вы предоставляете эту способность? Я попытался создать временный файл и открыть его снова, чтобы получить два дескриптора файла, но второе открытие не удается.
Вот создание:
FFileSystem := CreateFile(PChar(FFileName),
GENERIC_READ + GENERIC_WRITE,
FILE_SHARE_READ + FILE_SHARE_WRITE,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL OR
FILE_FLAG_RANDOM_ACCESS OR
FILE_ATTRIBUTE_TEMPORARY OR
FILE_FLAG_DELETE_ON_CLOSE,
0);
Вот второе открытие:
FFileSystem2 := CreateFile(PChar(FFileName),
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL OR
FILE_FLAG_RANDOM_ACCESS OR
FILE_ATTRIBUTE_TEMPORARY OR
FILE_FLAG_DELETE_ON_CLOSE,
0);
Я пробовал разные комбинации флагов, но пока безуспешно. При открытии второго файла всегда происходит сбой, с сообщениями о том, что к файлу нельзя получить доступ, так как он используется другим процессом.
Редактировать:
Хорошо, еще немного информации (я надеялся не потеряться здесь в сорняках ...)
Рассматриваемый процесс - это процесс сервера Win32, работающий на WinXP 64. Он поддерживает большие пространственные базы данных и хотел бы сохранить как можно большую часть пространственной базы данных в памяти в структуре кэша L1 / L2. L1 уже существует. L2 существует как «временный» файл, который остается в системном кеше Windows (это немного грязный трюк, но несколько обходит ограничения памяти win32). Win64 означает, что у меня может быть много памяти, используемой системным кэшем, поэтому память, используемая для хранения кэша L2, действительно учитывается в памяти процесса.
Несколько (потенциально много) потоков хотят одновременно получать доступ к информации, содержащейся в кэше L2. В настоящее время доступ сериализован, что означает, что один поток получает данные для чтения, в то время как большинство (или остальные) потоков блокируются в ожидании завершения этой операции.
Файл кэша L2 действительно записывается, но я рад глобально сериализовать / перемежать операции чтения и записи, пока я могу выполнять параллельные чтения.
Я знаю, что есть неприятные потенциальные проблемы параллелизма потоков, и я знаю, что есть десятки способов обшарить эту кошку в других контекстах. У меня есть этот конкретный контекст, и я пытаюсь определить, есть ли способ разрешить одновременный доступ к чтению потока в файле и в том же процессе.
Другой подход, который я рассмотрел, состоит в том, чтобы два раза разделить кэш L2 на несколько временных файлов, где каждый файл сериализует поток доступа, как текущий текущий файл кэш-памяти L2.
И да, этот несколько отдельный подход заключается в том, что 64-битный Delphi не будет с нами в ближайшее время: - (
Спасибо,
Raymond.