窗口 – 访问具有多个线程的单个文件

前端之家收集整理的这篇文章主要介绍了窗口 – 访问具有多个线程的单个文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要同时访问多个线程的文件。这需要同时完成,由于性能原因没有线程序列化。

文件特别使用’临时’文件属性创建,鼓励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,OPEN_EXISTING,0);

到目前为止,我已经尝试过各种标志的组合,没有成功。第二个文件打开总是失败,消息影响该文件无法被其他进程使用的文件访问。

编辑:

好的,一些更多的信息(我希望不要迷失在这里的杂草…)

所涉及的过程是WinXP 64上运行的Win32服务器进程。它维护大型空间数据库,并希望在L1 / L2缓存结构的内存中尽可能多地保留空间数据库。 L1已经存在。 L2作为一个“临时”文件存在于Windows系统缓存中(有点像肮脏的技巧,但是有一些Win32内存限制)。 Win64意味着我可以使用系统缓存大量的内存,因此用于保存L2缓存的内存将计入进程内存。

多个(可能很多)线程想要并发访问包含在L2缓存中的信息。目前,访问是序列化的,这意味着一个线程可以读取它的数据,而大多数(或其余的)线程在该操作完成之前被阻塞。

L2缓存文件确实写入,但是我很高兴全局串行/交错读写类型操作,只要我可以执行并发读取。

我知道有一个讨厌的潜在的线程并发问题,我知道有几十种方法来皮肤这只猫在其他情况下。我有这个特定的上下文,我正在尝试确定是否有一种方法允许并发线程读取访问文件和同一进程。

我考虑过的另一种方法是将L2缓存分成两个临时文件,其中每个文件以当前单个L2缓存文件的方式连接线程访问。

是的,这个有点绝对的做法是因为64位德尔福不会随时与我们在一起:-(

谢谢,
雷蒙德。

解决方法

是的,程序可以从不同的线程多次打开相同的文件。不过,您可以避免在写入文件的同时阅读文件。您可以使用 TMultiReadExclusiveWriteSynchronizer来控制对整个文件的访问。比起一个关键部分,它的序列化程度要小一些。要进行更精细的控制,请查看 LockFileEx以根据需要控制对文件特定区域的访问。写作时请求专属锁;当阅读时,共享锁。

对于您发布的代码,在初始共享标志中指定File_Share_Write意味着所有后续的打开操作也必须共享用于写入的文件。报价the documentation

If this flag is not specified,but the file or device has been opened for write access or has a file mapping with write access,the function fails.

您的第二个开放请求是说,它不希望任何人被允许写入该文件,而该句柄保持打开。既然已经有另一个句柄打开了,那么允许写入,第二个请求就无法实现了。 GetLastError应该返回32,这是Error_Sharing_Violation,正是文档说明应该发生的。

指定File_Flag_Delete_On_Close表示所有后续打开的请求需要共享要删除文件文件再次:

Subsequent open requests for the file fail,unless the FILE_SHARE_DELETE share mode is specified.

然后,由于第二个打开请求共享要删除文件,所有其他打开的句柄也必须共享才能删除文件

If there are existing open handles to a file,the call fails unless they were all opened with the FILE_SHARE_DELETE share mode.

所有的人都分享一下,没有任何人分享

FFileSystem := CreateFile(PChar(FFileName),Generic_Read or Generic_Write
  File_Share_Read or File_Share_Write or File_Share_Delete,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 or File_Share_Write or File_Share_Delete,Open_Existing,0);

换句话说,除了第五个参数之外,所有的参数是相同的。

这些规则适用于在同一线程上打开的两次尝试以及来自不同线程的尝试。

猜你在找的Delphi相关文章