【发布时间】:2009-10-27 17:39:41
【问题描述】:
我需要使用多个线程同时访问一个文件。这需要同时完成,出于性能原因没有线程序列化。
该文件特别是使用“临时”文件属性创建的,该属性鼓励 Windows 将文件保存在系统缓存中。这意味着大多数时候读取的文件不会靠近磁盘,而是会从系统缓存中读取文件的一部分。
能够同时访问此文件将显着提高我的代码中某些算法的性能。
所以,这里有两个问题:
- 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);
到目前为止,我已经尝试了各种标志组合,但没有成功。第二个文件打开总是失败,并提示无法访问该文件,因为它正被另一个进程使用。
编辑:
好的,更多信息(我希望不要在这里迷路......)
有问题的进程是在 WinXP 64 上运行的 Win32 服务器进程。它正在维护大型空间数据库,并希望将尽可能多的空间数据库保留在内存中的 L1/L2 缓存结构中。 L1 已经存在。 L2 作为“临时”文件存在,它保留在 Windows 系统缓存中(这有点肮脏,但在某种程度上绕过了 win32 内存限制)。 Win64 意味着我可以让系统缓存使用大量内存,因此用于保存 L2 缓存的内存确实计入进程内存。
多个(可能很多)线程想要同时访问 L2 缓存中包含的信息。目前,访问是序列化的,这意味着一个线程可以读取它的数据,而大多数(或其余)线程被阻塞等待该操作的完成。
L2 缓存文件确实被写入,但我很乐意全局序列化/交错读取和写入类型操作,只要我可以执行并发读取。
我知道存在令人讨厌的潜在线程并发问题,并且我知道在其他情况下有几十种方法可以给这只猫剥皮。我有这个特定的上下文,我正在尝试确定是否有办法允许在文件内和同一进程内进行并发线程读取访问。
我考虑过的另一种方法是将二级缓存分成多个临时文件,其中每个文件以当前单个二级缓存文件的方式序列化线程访问。
是的,这种有点绝望的方法是因为 64 位 Delphi 不会很快出现在我们身边 :-(
谢谢, 雷蒙德。
【问题讨论】:
标签: windows multithreading delphi file-io