简体   繁体   English

IO完成端口和OVERLAPPED管理

[英]IO Completion Ports and OVERLAPPED management

How win32 manages instances of OVERLAPPED struct in context of two functions: win32如何在两个函数的上下文中管理OVERLAPPED结构的实例:

GetQueuedCompletionStatus
PostQueuedCompletionStatus
  1. When I call GetQueuedCompletionStatus does win32 free instance of OVERLAPPED struct or I must do it by my self? 当我调用GetQueuedCompletionStatus时,确实是我的自己的win32 free实例的OVERLAPPED结构吗?

  2. When I send data with PostQueuedCompletionStatus does win32 copy it to internal structs? 当我使用PostQueuedCompletionStatus发送数据时,win32会将其复制到内部结构吗? When I must free memory of sent data? 什么时候我必须释放发送数据的内存?

  3. Where I could find some picture with scheme of processing of OVERLAPPED data between GetQueuedCompletionStatus, PostQueuedCompletionStatus and IOCP queue? 在哪里可以找到一些在GetQueuedCompletionStatus,PostQueuedCompletionStatus和IOCP队列之间处理OVERLAPPED数据的方案?

The OVERLAPPED structure must exist from when a successful I/O operation (or manual PostQueuedCompletionStatus() ) executes until the OVERLAPPED emerges from a call to GetQueuedCompletionStatus() . OVERLAPPED结构必须存在于成功的I / O操作(或手动PostQueuedCompletionStatus() )执行时,直到OVERLAPPED从对GetQueuedCompletionStatus()的调用中出现。

You are responsible for the lifetime of the structure. 您负责结构的生命周期。

You'll see from the MSDN docs that GetQueuedCompletionStatus() actually takes "a pointer to a variable that receives the address of the OVERLAPPED structure that was specified when the completed I/O operation was started.". 您将从MSDN文档中看到, GetQueuedCompletionStatus()实际上是“指向一个变量的指针,该变量接收完成的I / O操作启动时指定的OVERLAPPED结构的地址。” What you actually get out of that call is a pointer to the original OVERLAPPED that you passed when you made the PostQueuedCompletionStatus() call (or initiated an overlapped I/O operation). 您实际从该调用中得到的是指向您在进行PostQueuedCompletionStatus()调用(或启动重叠的I / O操作)时传递的原始OVERLAPPED的指针。

This is all actually very useful as the "normal" way to use the OVERLAPPED structure is to place it inside a larger structure which holds all of the 'per operation' information that you might need - so it's the ideal way to navigate directly from the limited information that you're given when you call GetQueuedCompletionStatus() to, for example, the data buffer that you used in your overlapped read call... 这实际上非常有用,因为使用OVERLAPPED结构的“正常”方式是将它放在一个更大的结构中,该结构包含您可能需要的所有“每个操作”信息 - 因此它是直接从导航中导航的理想方式。您在调用GetQueuedCompletionStatus()时给出的有限信息,例如,您在重叠读取调用中使用的数据缓冲区...

I find the best way to deal with OVERLAPPED structures is to a) embed them in the buffer you're using for read/write b) reference count them and c) return them to a pool for reuse when the ref count drops to 0. 我发现处理OVERLAPPED结构的最佳方法是a)将它们嵌入到用于读/写的缓冲区中b)引用计数它们和c)当ref count降为0时将它们返回到池中以便重用。

I have some source code that you could download ( here ) which may make this a little easier to understand (it's a full IOCP server example so it's a little complex, but it works and shows how these things can be used). 我有一些你可以下载的源代码( 这里 )可能会让它更容易理解(这是一个完整的IOCP服务器示例,所以它有点复杂,但它可以工作并显示如何使用这些东西)。

  1. You should pass a the address of a OVERLAPPED * to GetQueuedCompletionStatus . 您应该将OVERLAPPED *的地址传递给GetQueuedCompletionStatus This gets filled in with the value passed to PostQueuedCompletionStatus . 这将通过传递给PostQueuedCompletionStatus的值填充。
  2. You should not free this data in the PostQueuedCompletionStatus context. 您不应该在PostQueuedCompletionStatus上下文中释放此数据。 It should be done by the context using GetQueuedCompletionStatus . 它应该使用GetQueuedCompletionStatus通过上下文完成。 (Assuming it was allocated dynamically in the first place - there is no requirement that it is a dynamically allocated structure, it could be taken out of a fixed pool, or be allocated on the stack of a function that doesn't return until it has been signalled that the operation is complete). (假设它是首先动态分配的 - 不要求它是动态分配的结构,它可以从固定池中取出,或者在函数的堆栈上分配,直到它具有已经发出信号表明操作已经完成)。
  3. I'm not sure there is such a picture. 我不确定有这样的照片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM