WriteFile/ReadFile 是否在没有 FILE_FLAG_OVERLAPPED 但使用 OVERLAPPED 结构的情况下在同一句柄上线程安全打开?

Is WriteFile/ReadFile on Same Handle Thread-Safe Opened Without FILE_FLAG_OVERLAPPED but using OVERLAPPED structure?

很明显,如果您使用 FILE_FLAG_OVERLAPPED 打开文件,则需要提供 OVERLAPPED 结构,并且在 returns ERROR_IO_PENDING 时需要等待,如果您不这样做't 提供 hEvent 它等待文件句柄。在这种情况下,等待文件句柄是不可靠的,因为任何完成的操作都会向文件句柄发出信号。

现在,如果在没有 FILE_FLAG_OVERLAPPED 的情况下打开,您仍然可以提供 OVERLAPPED 结构。假设您在没有 hEvent 的情况下提供它,或者根本没有提供 OVERLAPPED,它在内部做什么?如果它等待文件句柄,在多线程应用程序中似乎不可靠,在多个线程中使用相同的句柄来进行文件 IO。

如果它是多线程不可靠的,并且每个 IO 都需要一个 hEvent,那么 CreateEvent 涉及多少开销?如果不是,它是否会在内部创建一个事件并且是否具有相同的开销?

我需要在支持库中提供以重叠模式打开物理驱动器的功能,但仍然支持它们同步操作。将创建一组用于重叠 read/write 的新函数。对于现有的函数调用,我打算等待句柄,但我认为这是一个问题。因此,我可以每次都创建一个事件,或者创建一个共享的一次性事件并使用 Mutex 来序列化请求,只有这样才能消除任何 NCQ 类型的性能提升,尤其是在不使用写缓存的情况下。了解 Windows 内部的作用会有很大帮助。

TIA!!

是的,很安全。

发出事件或文件句柄的信号是为了 user-mode 等待操作的代码。驱动程序在内部使用完全不同的同步方案——IRP(I/O 请求数据包)。多次操作不会像你担心的那样意外完成错误的请求。

(事实上,幕后并没有同步I/O模型。所有I/O都是使用IRP和continuation-passing-style完成的。模拟用户模式下的同步操作通过执行异步内核 I/O 并将当前线程标记为 non-runnable 挂起该操作。请注意,它挂起在操作上,而不是事件对象或文件对象上。)