来自MSDN的关于CreateIoCompletionPort函数中的CompletionKey的评论:
使用CompletionKey参数可帮助您的应用程序跟踪已完成的I/O操作.CreateIoCompletionPort不使用此值进行功能控制; 相反,它在与I/O完成端口关联时附加到FileHandle参数中指定的文件句柄.对于每个文件句柄,此完成键应该是唯一的,并且它在整个内部完成排队过程中伴随文件句柄.当完成数据包到达时,它将在GetQueuedCompletionStatus函数调用中返回.PostQueuedCompletionStatus函数还使用CompletionKey参数来排队您自己的专用完成数据包.
上述言论给我一个问题.为什么使用CompletionKey,因为我们可以将用户上下文与扩展重叠结构中的文件句柄相关联,如下所示:
typedef struct s_overlappedplus
{
OVERLAPPED ol;
int op_code;
/*we can alternatively put user context over here instead of CompletionKey*/
LPVOID user_context;
} t_overlappedplus;
Run Code Online (Sandbox Code Playgroud)
完成后通过CONTAINING_RECORD宏进行检索?
很酷,我只相信CompletionKey是每个句柄的上下文,而扩展的重叠结构是每I/O一个.但是这种设计背后的哲学是什么,在什么情况下可以使用CompletionKey而不是在用户上下文中使用扩展的重叠结构?
windows multithreading winsock overlapped-io io-completion-ports
在Mac OS X上是否有任何等效的IO COmpletion端口用于在文件上实现异步IO ....
谢谢....
我最近在Windows上知道了这个名为IOCP的东西,我开始搜索有关它的更多信息,但我找不到任何最新版本(大多数示例都在代码项目上差不多5年)并且没有太多的指南或者教程.任何人都可以通过在线教程或示例项目(您编写并可以共享或其他开源项目)的形式推荐任何有关它的最新资源,甚至可以推荐一本关于它的书籍,因为如果它听起来好像我打算使用它它广泛,所以我会投资它.
谢谢.
当我们的应用程序依赖外部服务时,使用异步编程很重要的原因之一是允许ASP.NET使用IO完成端口,而不是阻止等待外部服务响应的线程,ASP.NET可以将执行停放在IO完成端口并使用该线程来访问另一个请求,只要外部服务响应,然后ASP.NET再次获取该执行并恢复它.这样,没有线程被阻塞.
异步方法的一个例子是:
[HttpPost]
public async Task<ActionResult> Open(String key)
{
Foo foo= await _externalService.GetFoo(key);
return View(foo);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们对外部服务使用多个请求会发生什么?ASP.NET如何处理它?
[HttpPost]
public async Task<ActionResult> Open()
{
List<Task<Foo>> tasks = new List<Task<Foo>>();
foreach (var key in this.Request.Form.AllKeys)
tasks.Add(_externalService.GetFoo(key));
var foos = await Task.WhenAll(tasks);
Foo foo = null;
foreach (var f in foos)
{
if (foo == null && f != null)
foo = f;
else
foo.Merge(f);
}
return View(foo);
}
Run Code Online (Sandbox Code Playgroud)
它还在使用IO完成端口吗?或者因为Task.WhenAll阻塞线程?
asp.net multithreading task-parallel-library async-await io-completion-ports
使用I/O完成端口与使用RegisterWaitForSingleObject线程池线程等待I/O完成之间有什么区别?
其中一个更快,如果是,为什么?
假设您正在ReadDirectoryChangesW使用 I/O 完成端口执行异步操作(如)。对于每次调用该函数,您分配一个OVERLAPPED结构(可能带有一些附加数据)以在 I/O 完成回调中使用。然后在回调中,在使用OVERLAPPED结构后,您使用作为参数提供的指针释放内存。
现在让我们说是时候关闭一切并取消任何挂起的异步调用了。是否有可以调用的函数来检索指向OVERLAPPED任何当前挂起的 I/O 操作中使用的结构的指针,以便您可以释放内存?
我有这段代码,它基本上使用 IO 完成端口写入文件 5 次。正如你所猜到的,它的效果不是很好。问题是我希望将“hello”写入文件 5 次,但最终总是只写入一个“hello”。我很困惑,因为程序打印了 5 次“写了 5 个字节”,所以我认为写操作没有问题。
任何人都可以看到这个问题吗?
#include <windows.h>
#include <stdio.h>
#define IOCP_NOMORE 3
#define IOCP_WRITE 1
HANDLE hWriteIoCp;
typedef struct _OVERLAPIOINFO {
OVERLAPPED overlapped;
HANDLE hFile;
} OVERLAPIOINFO;
HANDLE CreateNewCompletionPort()
{
return CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
}
BOOL AssociateFileCompletionPort(HANDLE hIoPort, HANDLE hFile, DWORD completionKey)
{
HANDLE h = CreateIoCompletionPort(hFile, hIoPort, completionKey, 0);
return h == hIoPort;
}
DWORD WINAPI SaveFileWorkerThread(void *empty)
{
ULONG_PTR completionKey;
BOOL completionStatus;
DWORD bytesTransferred;
DWORD err;
OVERLAPPED *overlap;
OVERLAPIOINFO *info; …Run Code Online (Sandbox Code Playgroud) 我正在使用 I/O-Completion Port 编写一个小的服务器-客户端的东西。
我通过我的完成端口通过 AcceptEx 成功连接了服务器和客户端。客户端连接后,客户端套接字与完成端口相关联,并在该套接字上调用对 WSARecv 的重叠调用。
一切正常,直到我关闭客户端测试程序。
GetQueuedCompletionStatus()退货FALSE和GetLastError退货
ERROR_NETNAME_DELETED
,这对我来说很有意义(在我阅读了 MSDN 上的描述之后)。
但我的问题是,我认为调用GetQueuedCompletionStatus会返回一个数据包,表明由于套接字关闭而失败,因为WSARecv会返回适当的返回值。由于情况并非如此,我不知道哪个客户端的套接字导致了错误并且无法按照我需要的方式行事(释放结构,清理此特定连接等)...
关于如何解决这个问题的任何建议或提示?
谢谢:)
编辑:http : //codepad.org/WeYINasO <- 负责的代码......“错误”发生在 while 循环的第一个函数开始处(对它的调用GetCompletionStatus()只是 GetQueuedCompletionStatus() 工作正常的包装器其他情况)[确实把它贴在那里,因为它在这里看起来又脏又乱]
asynchronous ×3
winapi ×3
windows ×3
c ×2
winsock ×2
asp.net ×1
async-await ×1
c++ ×1
file-io ×1
getlasterror ×1
io ×1
iocp ×1
visual-c++ ×1