Мне нужно получить доступ к файлу одновременно с несколькими потоками. Это необходимо сделать одновременно, без сериализации потоков по причинам производительности.
Файл, в частности, был создан с атрибутом "временного" файла, который побуждает окна хранить файл в системном кеше. Это означает, что большую часть времени чтение файла обычно не приближается к диску, но будет считывать часть файла из системного кеша.
Возможность одновременного доступа к этому файлу значительно улучшит производительность некоторых алгоритмов в моем коде.
Итак, здесь есть два вопроса:
- Возможно ли, чтобы окна одновременно обращались к одному файлу из разных потоков?
- Если да, то как вы предоставляете эту способность? Я попытался создать временный файл и снова открыть файл, чтобы предоставить два дескриптора файлов, но второй открыть не удается.
Здесь создаются:
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 записывается, но я рад глобально сериализовать/перемежать операции чтения и записи, если я могу выполнять одновременные чтения.
Я знаю, что есть неприятные потенциальные проблемы с потоком concurrency, и я знаю, что есть десятки способов скинуть этот кот в других контекстах. У меня есть этот конкретный контекст, и я пытаюсь определить, есть ли способ разрешить параллельный доступ к чтению нитей в файле и в рамках одного и того же процесса.
Еще один подход, который я рассмотрел, - это два разделенных кэша L2 во множество временных файлов, где каждый файл сериализует поток, доступный для текущего одиночного файла кэша L2.
И да, этот несколько отвратительный подход заключается в том, что 64-битный Delphi не будет с нами в ближайшее время: - (
Спасибо, Рэймонд.