问题标签 [overlapped-io]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1045 浏览

c++ - 使用重叠结构进行回调?

对于使用 IO 完成端口的异步 IO,我有自己的重叠结构。

现在我收到读/写完成的通知。我可以将 CALLBACK 函数作为重叠结构中的参数传递吗?

这将允许我根据我传递的重叠结构的类型指定各种回调函数

有人对此有任何运气吗?

0 投票
0 回答
1623 浏览

c++ - 命名管道上的异步读取操作?

我想在命名管道上异步接收数据。以下是我的服务器代码:

客户端代码成功“同步”发送消息。但是每次服务器调用 readFile 时,它​​都会返回 ERROR_IO_PENDING 并且 GetOverlappedResult 会返回 ERROR_IO_INCOMPLETE。它继续循环。我正在使用 windows vista 和 Visual Stdio 2010。这段代码可能有什么问题。

问候,库拉姆。

0 投票
1 回答
629 浏览

windows - GetLastError 返回 ERROR_OPERATION_ABORTED 时,GetOverlappedResult 的 lpNumberOfBytesTransfered 参数是否有效?

在我的项目中,我需要读取和写入串行端口(RS232)。我正在使用重叠 IO 并使用两个单独的线程进行读写。

当我发出没有立即完成的写操作时,我开始等待 (WaitForMultipleObjects) 两个事件;分配给重叠结构的 hEvent 成员的事件,以及一个停止事件。当我想停止线程时,我通过调用 SetEvent() 发出停止事件信号。这会导致等待函数返回。因为写操作仍在等待中,所以我通过调用 CancelIO() 来取消操作。然后,我再次等待操作完成,现在使用 GetOverlappedResult() 并将 bWait 参数设置为 True。操作完成后,GetOverlappedResult() 返回 False,GetLastError() 返回 ERROR_OPERATION_ABORTED。

现在这是我的问题:

当 GetOverlappedResult() 返回 False,GetLastError() 返回 ERROR_OPERATION_ABORTED(表示操作已完成但已取消)时,lpNumberOfBytesTransfered 参数是否有效?换句话说,lpNumberOfBytesTransfered 是否在取消之前给了我实际的写入字节数?还是在这种情况下未定义 lpNumberOfBytesTransfered 参数?

0 投票
1 回答
352 浏览

multithreading - 多线程IOCP服务器中重叠结构的存储与管理

使用 LINKED LIST 存储重叠结构是个好主意吗?

我的重叠结构看起来像这样

当 iocp 服务器启动时,我在链接列表中分配(例如)其中的 5000 个。此列表的开头存储在全局变量 PPER_IO_CONTEXT OvlList 中。我必须补充一点,我只在必须向所有连接的客户端发送数据的情况下使用这个链表。当 Wsasend 发布或 GQCS 收到通知时,更新链表(我使用 EnterCriticalSection 进行同步)。提前感谢您对更好的存储(缓存)重叠结构的提示、意见和建议。

0 投票
1 回答
415 浏览

c - windows中依赖重叠io的编码模式

我是一名 linux 程序员,最近参与了将一个基于 epoll 的客户端与两个用 c 编写的文件描述符移植到 windows 中。
如您所知,在使用 epoll 或 select 的 linux 中(我知道 windows 支持 select,但它根本没有效率)您可以阻塞文件描述符,直到文件描述符准备好并且您可以知道它何时准备好写入和何时读取。

我已经查看了 Windows IOCP,在微软世界中重叠 io 听起来不错。但在所有示例中,它都用于多客户端服务器,每个客户端的套接字都独立于其他套接字。

使用完成端口,可以为每个客户端创建一个completionKey结构,并在struct中放入一个变量,并在调用WSArecv时读取它,并在WSAsend时读取,另一个变量指示套接字值并从GetQueuedCompletionStatus中检索它们以知道该怎么做,如果对套接字进行了写入,则进行读取,反之亦然。

但就我而言,文件描述符(fd)确实重叠。从一个 fd 读取,对另一个 fd 进行读取和写入,这使得在 GetQueuedCompletionStatus 结果中很难知道每个 fd 实际发生了什么操作,因为每个 fd 都有一个 completionKey。为了清楚起见,请考虑:

有两个句柄 fd1 和 fd2,completionKey1 持有 f1 的句柄和状态,fd2 的 completionKey2 和 completionKey 变量用于从 GetQueuedCompletionStatus 检索完成。

在上面的代码中,会出现一些更改完成键将覆盖挂起的读取或写入的情况,并且结果完成键->状态将是错误的(例如它将报告读取而不是写入),最糟糕的是缓冲区将被覆盖。如果我对完成键使用锁定,则会导致死锁情况。

在查看 WSAsend 或 WSArecv 之后,注意到可以为每个发送或接收设置一个重叠参数。但这会导致两个主要问题。根据 WSAOVERLAPPED 结构:

首先,其中没有放置状态和适当缓冲区的位置,并且其中大部分是保留的。

其次,如果可以解决第一个问题,我需要检查是否没有可用的重叠剩余并且它们都用于挂起的操作,为每次读写分配一个新的,因为客户端会这样忙,它可能会发生很多,此外,管理那些重叠的池是一件令人头疼的事情。所以我错过了什么还是微软搞砸了这个?

而且由于我不需要多线程,还有其他方法可以解决我的问题吗?
提前感谢
编辑
正如我猜想的那样,我在使用重叠结构时提到的第一个问题有答案,我只需要创建另一个包含所有缓冲区和状态等的结构,并将 OVERLAPPED 作为第一个文件。现在你解决我的其他问题;)

0 投票
0 回答
1588 浏览

c++ - ReadFile 错误并重叠

我对 ReadFile 有问题并重叠。

首先我使用 ReadFile 与 0 重叠

使用 for(),我可以使用 printf() 查看字节

现在我有一个数量很大的变体

我需要使用 ReafFile 两次,这第二次是使用带有 offset 和 highoffset 值的重叠()

但是 for() 打印的字节与第一个 ReadFile 相同,我尝试使用 memset() 清理缓冲区或使用另一个缓冲区,但始终显示相同的字节

据说 Overlapped() 告诉 ReadFile 应该去哪里,并读取 1024 个字节,并将其保存在缓冲区中,但没有任何反应,缓冲区具有相同的第一个字节,重叠 () = 0

这是完整的代码

VB.NET

0 投票
1 回答
915 浏览

c++ - 为什么 WSASend 返回 0 但仍然调用完成例程?

文档清楚地说,如果 WSASend 立即完成,您将获得 WSA_IO_PENDING,但这永远不会发生。我总是得到 0,并且 dwBytesTransferred 总是与我发送的字节匹配。但是,似乎有时会调用我的完成例程,有时则不会。我为发送分配了缓冲区,所以如果不调用完成例程,我需要释放缓冲区。

我有三个即兴计数器,m_dwAsyncSend、m_dwSyncSend 和 m_dwCompletions。m_dwAsycSend 始终为零,并且 m_dwSyncSend 和 m_dwCompletions 始终相距甚远,因为一个 m_dwSyncSend 可能是 750 而 m_dwCompletions 是 2。线程有很多时候是可警告的,所以我认为我不会那样饿死它。

这让我疯了!现在是午夜之后,我整天都在这。如果其中任何一个不连贯,我会责备它!

这是代码,我认为您不需要类文件来查看我在做什么。

0 投票
1 回答
220 浏览

c++ - OVERLAPPED 结构的引用计数

我发现了一篇我觉得很有趣的文章。只有一件事我无法理解。( http://molecularmusings.wordpress.com/2011/08/31/file-system-part-1-platform-specific-api-design/ ) 作者描述了一个能够处理同步和异步文件操作的 File 类. 对于异步操作,他使用了一个自包含对象,该对象在内部跟踪异步操作。该类如下所示:

并且是这样使用的:

现在我想知道:ReferenceCountedItem<OVERLAPPED>* m_overlapped;变量的作用是什么?我知道这会以某种方式计算引用,但我不确定它是如何在这里使用的,特别是因为构造函数没有通过OVERLAPPED结构。这个类现在如何了解or方法OVERLAPPED中使用的结构?我试图实现这个类,因为它没有在文章中指定:ReadAsyncWriteAsyncReferenceCountedItem

我主要不确定这一切是如何结合在一起的。也许有人可以对此进行更多解释。如果您需要更多信息,请告诉我。

0 投票
0 回答
248 浏览

c++ - 使用 OVERLAPPED 操作(和 IOCP?)读取和细化多个文件

我正在尝试找出一种方法来改进我制作的 C++ Win32 程序,该程序基本上递归遍历给定文件夹,并为每个给定文件计算一个哈希(比如说 MD5,但它可能是任何类型的 CPU 昂贵计算) . 由于这是一个 I/O 绑定的应用程序,大部分时间进程都在等待 I/O 完成,因此不会使用尽可能多的 CPU。即使使用线程池执行此操作也可能(我错了吗?)不能解决问题,每个线程都会阻塞等待 I/O 完成,另外还会有上下文切换开销。

所以我开始考虑使用重叠读取来执行此操作,每次我收集一个新文件进行处理时,我都会将一个非阻塞读取操作排入队列,让一个线程处理完成回调并对我收到的每个块进行块哈希处理从队列本身...理论上这应该避免进程挂在 I/O 等待上,我应该注意到 CPU 使用率增加,从而整体加速。

我有以下问题:

  • 我假设这会提高应用程序的整体性能,对吗?如果不是,为什么?
  • I/O 完成事件的排序方式是否与读取操作相同?我的意思是,如果我从文件的偏移量 A、B 和 C 中读取 N 个字节,我会按该顺序获得 A、B 和 C 的完成事件,还是它们会以不可预测的顺序到达?
  • 我正在寻找一个库或一些代码示例来实现整个机制,我应该使用 IOCP,还是简单地使用带有自定义回调的 RegisterWaitForSingleObject ?我似乎没有找到多个文件 I/O 的示例,我发现的所有内容都只是单个文件上重叠读取的示例,或者带有套接字的 IOCP,你能指出我正确的方向吗?
  • 在这种情况下,线程池不是没用吗?单线程方法应该足够好(例如遵循 nginx/libevent 方法),对吗?

请不要用替代解决方案回答某些问题,我只想以最好的方式实现一个 OVERLAPPED 操作队列,我对其他任何事情都不感兴趣(当然,除非证明对我的场景更有效)。

编辑:

目前软件的实现是什么(当然app不完全是这样,只是给个思路):

谢谢。

0 投票
1 回答
2157 浏览

winsock2 - 当完成数据包可用时,如何防止 I/O 完成端口阻塞?

我有一个服务器应用程序,它使用Microsoft 的 I/O 完成端口 (IOCP)机制来管理异步网络套接字通信。总的来说,这种 IOCP 方法在我的环境中表现得非常好。但是,我遇到了一个极端情况,我正在寻求指导:

出于测试的目的,我的服务器应用程序正在通过千兆位 LAN 将数据流式传输(比如说 ~400 KB/秒)到单个客户端。一切都很好……直到我断开客户端的以太网电缆与 LAN 的连接。以这种方式断开电缆可防止服务器立即检测到客户端已消失(即客户端的 TCP 网络堆栈不会向服务器发送连接终止的通知)

同时,服务器继续对WSASend客户端进行调用......由于这些调用是异步的,它们似乎“成功”(即数据由操作系统缓冲在套接字的出站队列中)。

虽然这一切都在发生,但我有 16 个线程被阻塞GetQueuedCompletionStatus,等待从端口检索完成数据包,因为它们变得可用。在断开客户端的电缆之前,有源源不断的完成数据包流。现在,一切(如预期)似乎都停止了……大约 32 秒。32 秒后,IOCP 重新开始操作,返回FALSE一个非空lpOverlapped值。 GetLastError返回121(信号量超时期限已过。)我只能假设错误121是WSASendTCP堆栈确定客户端消失后最终超时的产物?

我很好,网络堆栈需要 32 秒才能确定我的客户端已经消失。问题是,当系统做出这个决定时,我的 IOCP 瘫痪了。例如,在接收到失败的完成数据包(指示错误 121)之前,WSAAccept被阻塞的 16 个线程中的任何一个都不会处理发布到同一 IOCP 的事件。GetQueuedCompletionStatus

我最初的解决这个问题的计划涉及WSAWaitForMultipleEvents在调用后立即使用WSASend。如果套接字事件没有在(例如 3 秒)内发出信号,那么我终止套接字连接并继续前进(希望防止对我的 IOCP 产生广泛的阻塞效应)。不幸的是,WSAWaitForMultipleEvents似乎从来没有遇到过超时(所以异步套接字可能是由于异步而发出信号的?或者将数据复制到 TCP 队列有资格获得信号?)

我仍在尝试解决这一切,但希望有人对如何防止 IOCP 挂起有一些见解。

其他细节:我的服务器应用程序在 8 核的 Win7 上运行;IOCP配置为最多使用8个并发线程;我的线程池有 16 个线程。大量的 RAM、处理器和带宽。

提前感谢您的建议和建议。