问题标签 [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 回答
2154 浏览

asynchronous - 提升 asio 异步与阻塞读取、udp 速度/质量

我有一个用 C# 编写的快速而肮脏的概念证明应用程序,它从网络读取高数据速率多播 UDP 数据包。由于各种原因,完整的实现将用 C++ 编写,我正在考虑使用 boost asio。C# 版本使用线程通过阻塞读取来接收数据。如果计算机负载很重(通常在另一个线程中处理这些数据包),我会遇到一些丢弃数据包的问题。

我想知道的是 boost 中的异步读取操作(在 windows 中使用重叠 io)是否有助于确保我接收数据包和/或减少接收数据包所需的 cpu 时间。执行阻塞读取的单线程非常简单,使用异步读取似乎更复杂,但我认为如果它提供更高的性能或在重负载系统上丢弃更少的数据包,那将是值得的。目前数据速率应不高于 60Mb/s。

0 投票
1 回答
3459 浏览

delphi - 重叠 I/O 操作期间的串行端口和处理错误

我最近一直在做串行通信,所以我准备了一个类,它是所有负责读取、写入等的 Windows API 函数的简单接口。这个类中的所有 I/O 操作都是异步处理的。

在我开始我的问题之前,让我告诉你我是如何从串口写入和读取数据的(这只是读取功能,因为写入的结构完全相同,所以没有必要同时呈现它们) .

在您问我为什么在此函数等待读取操作完成时为重叠操作打开串行端口之前,这是我的解释 - 只有当以这种方式打开串行端口时,我才能指定 WaitCommEvent() 方法等待事件的时间。如果我为非重叠操作打开端口,WaitCommEvent() 将阻塞,直到串行端口上出现一个事件,该事件并不总是发生,导致调用线程永远阻塞。

尽管如此,让我们专注于上面的 Read() 函数。

1)首先,我等待设置事件没有任何时间限制。当前线程是否有可能因为某种原因而永远阻塞?我不知道我是否可以 100% 确定事件迟早会由异步执行读取操作的线程设置。我知道当串行端口的读取超时都设置为零时,读取操作将在读取给定的字节数之前完成,但这是我知道的一种行为。我的问题涉及会导致事件永远不会被设置和 WaitFor() 方法永远等待的意外情况 - 它可能会发生吗?

2) WaitFor() 可能会返回 wrError ,这表明在等待操作期间发生了一些错误(但这根本与重叠读取操作无关,对吧?)。因此我认为我不应该再等待读取操作完成,因为事件句柄可能不再可用,对吧?所以我调用 CancelIO() 方法取消读取操作,等待异步执行取消读取的线程设置事件,然后才引发异常。我等待该线程取消读取,因为如果我立即离开我的 Read() 方法(不取消 I/O),我会导致该线程将其数据(重叠的记录数据)写入本地变量,这将那么就不再有效了,对吧?另一方面,

如果您告诉我上述陈述是否属实,我将不胜感激,并请发表评论。

非常感谢您提前。

0 投票
2 回答
482 浏览

c# - 跨进程的异步 IO

全部:

我正在写一个日志记录解决方案。可用的日志端点之一是文本文件。假设我想从多个进程写入该文件:我可以共享打开它,并使用命名互斥锁来控制对文件的并发访问(假设所有访问都发生在同一台机器上)。但后来我开始想知道异步 IO。在一个进程中,我可以使用 BeginWrite 异步发出我的写入。跨进程或跨机器问题呢?在这些情况下异步 IO 安全吗?

(假设当我调用 BeginWrite() 时,我传递的缓冲区包含应该一起保存在一个逻辑“记录”中的所有内容)

0 投票
2 回答
4394 浏览

c# - 命名管道 - 异步查看

当以异步模式打开的 System.IO.Pipe.NamedPipeServerStream 有更多数据可供读取时,我需要找到一种通知方式——WaitHandle 将是理想的。我不能简单地使用 BeginRead() 来获得这样的句柄,因为我可能会被另一个想要写入管道的线程发出信号 - 所以我必须释放管道上的锁并等待写入完成,并且 NamedPipeServerStream 没有 CancelAsync 方法。我还尝试调用 BeginRead(),然后在线程收到信号时调用管道上的 win32 函数 CancelIO,但我认为这不是一个理想的解决方案,因为如果在数据到达和处理时调用 CancelIO,它将被删除 - 我仍然希望保留这些数据,但在写入之后稍后处理它。

在上面的文字有点不清楚的情况下,这大概是我想做的事情......

0 投票
3 回答
7302 浏览

c# - C# 和本机重叠 I/O

我有一个要包装的 C dll,以便我可以从 C# 调用它。一个函数使用事件在状态发生变化时通知您,并且想出处理它需要一些挖掘。它似乎工作正常,但我很好奇是否有人比我有更多的经验并且可以提供任何建议。

该函数在 dll 的 .h 文件中定义为:

调用它的示例 C 代码:

这就是我在 C# 中处理它的方式:

我不清楚的一件事是需要 userData。NotifyStateChange 只是触发一个事件,它不返回任何数据。将 null userData 传递给 Pack() 似乎工作正常,但我担心 userData 可能会在我不知道的情况下发生一些事情。

如果有更合适的方法可以做到这一点,我很感激任何建议。

埃里克

0 投票
1 回答
1388 浏览

asynchronous - 取消 WinUSB 异步控制传输

对于使用 WinUSB 的用户应用程序(不是驱动程序),我将 WinUsb_ControlTransfer 与重叠 I/O 结合使用来异步发送控制消息。是否可以取消异步操作?WinUsb_AbortPipe 适用于所有其他端点,但在传递控制端点时会给出“无效参数”错误(0x00 或 0x80 作为管道地址)。我还尝试了 CancelIo 和 CancelIoEx,但都在 WinUSB 句柄上给出了“无效句柄”错误。我能找到的唯一相关信息是http://www.winvistatips.com/winusb-bugchecks-t335323.html,但没有提供解决方案。这是不可能的吗?

0 投票
2 回答
1609 浏览

file-io - 以快速方式读取网络驱动器上的整个文件(Windows、C/C++、C#、...)

最近我在读取网络驱动器上的大文件时遇到问题,我无法确定我可能做错了什么。我在 C++(非托管)和 C# 中都进行了尝试,并且两者的性能大致相同......这有点糟糕。

有时它会在网络上以 4 KB/sa 的速度读取文件,但如果该文件位于本地 HD 上,它将轻松实现 HD 可以输出的最大数据速率。那就是一次读取 64 KB 的块......我尝试使用更大的缓冲区,直到疯狂的数字,或者更小,它并没有太大的区别。

我在 C# 中尝试使用 FileStream 上的 BeginRead 和 C++ 中的 OVERLAPPED IO 的异步 IO 以及同步读取,它们都有相同的问题,这在网络上很慢。

我们想出的唯一解决方案是在实际读取文件之前使用本地 HD 上的 OS CopyFile 功能复制文件,但我对这种方法不太满意。看起来 CopyFile 正在做一些我们没有做的事情,这使得它比我们的方法快得多。

任何人都知道这是为什么?

0 投票
4 回答
1941 浏览

winapi - 根据 MSDN ReadFile() Win32 函数可能会错误地报告读取操作完成。什么时候?

MSDN 在其ReadFile()功能描述中指出:

如果 hFile 使用 打开FILE_FLAG_OVERLAPPED,lpOverlapped 参数必须指向一个有效且唯一的OVERLAPPED结构,否则该函数可能会错误地报告读取操作已完成。

我有一些应用程序违反了上述建议,我想知道问题的严重性。我的意思是该程序使用已创建的命名管道FILE_FLAG_OVERLAPPED,但它使用以下调用从中读取:

这意味着它NULL作为lpOverlapped参数传递。根据文档,该调用在某些情况下不应正常工作。我花了很多时间试图重现这个问题,但我无法做到!我总是在正确的时间将所有数据放在正确的位置。我只测试了命名管道。

有人知道我什么时候可以期望 ReadFile() 会错误地返回并报告成功完成,即使数据尚未在缓冲区中?为了重现问题,必须发生什么?文件、管道、套接字、控制台或其他设备是否会发生这种情况?我必须使用特定版本的操作系统吗?还是特定版本的读取(例如注册 I/O 完成端口的句柄)?或者读写进程/线程的特定同步?

或者什么时候会失败?这个对我有用 :/

请帮忙!

关于,马丁

0 投票
7 回答
2894 浏览

winapi - 是否可以将已为同步 I/O 打开的 HANDLE 更改为在其生命周期内为异步 I/O 打开?

现在,我在 Windows 中的大部分日常编程工作都围绕着各种 I/O 操作(管道、控制台、文件、套接字……)。我很清楚从/向不同类型的句柄读取和写入的不同方法(同步、异步等待事件完成、等待文件句柄、I/O 完成端口和可警报 I/O)。我们使用其中的许多。

对于我们的某些应用程序,只有一种方法来处理所有句柄将非常有用。我的意思是,程序可能不知道它收到了什么样的句柄,我们想使用,比如说,所有的 I/O 完成端口。

所以首先我会问:

假设我有一个句柄:

我的 I/O 进程从某个地方收到了它。有没有简单可靠的方法来找出它是用什么标志创建的?有问题的主要标志是FILE_FLAG_OVERLAPPED.

到目前为止,我知道的唯一方法是尝试将此类句柄注册到 I/O 完成端口(使用CreateIoCompletionPort())。如果成功,则使用 FILE_FLAG_OVERLAPPED 创建句柄。但是只有 I/O 完成端口必须使用,因为句柄不能在不关闭HANDLE h自身的情况下从它注销。

如果有一种简单的方法来确定 的存在FILE_FLAG_OVERLAPPED,那么我的第二个问题就会出现:

有什么办法可以将这样的标志添加到已经存在的句柄中?这将使最初为同步操作打开的句柄为异步打开。有没有办法创建相反的(FILE_FLAG_OVERLAPPED从异步中删除创建同步句柄)?

在阅读了 MSDN 并搜索了很多之后,我没有找到任何直接的方法。至少会有一些技巧可以做到这一点吗?CreateFile()就像使用函数或类似的东西以相同的方式重新创建句柄?甚至部分记录或根本没有记录的东西?

我需要这个的主要地方是确定进程应该从第三方应用程序发送给它的句柄中读取/写入的方式(或更改方式)。我们无法控制第三方产品如何创建它们的句柄。

亲爱的 Windows 大师:请帮助!

带着敬意

马丁

0 投票
1 回答
2410 浏览

windows - OVERLAPPED Win32 结构中的 hEvent 成员

当使用异步 I/O(或 Win32 术语中的“重叠”I/O)时,我们需要处理OVERLAPPED结构及其hEvent成员。如果 I/O 函数会延迟读取或写入操作,我们会得到一个ERROR_IO_PENDING错误代码,然后我们将等待异步操作完成一个WaitForXxxEvent函数,然后我们将调用GetOverlappedResult.

但是,如果 I/O 操作立即完成,我们将不会得到ERROR_IO_PENDING,并且在读取操作中,我们的读取缓冲区将立即被填满。但是OVERLAPPED::hEvent会员呢?它会被设置为信号状态吗?我还没有找到关于这一点的明确声明。

这个问题似乎毫无意义(如果我知道操作已经完成,为什么要处理该事件?),但是我有一个模仿重叠模式的库,我需要具有相同的确切行为。


正如edgar.holleis他的评论中指出的那样,Raymond Chen在他的博客中解释了这一点:http: //blogs.msdn.com/b/oldnewthing/archive/2014/02/06/10497096.aspx

如果异步 I/O 同步完成,是否会发出 OVERLAPPED 结构中的 hEvent 信号?

是的。

当 I/O 完成时(无论是同步还是异步),都会发出事件信号并且完成状态通知会排队。该 Get­Overlapped­Result/Ex函数可用于等待已经完成的 I/O;它只会立即返回。如果你问 HasOverlappedIoCompleted I/O 是否完成,并且 I/O 同步完成,它会正确报告,“是的,当然完成了。哎呀,很久以前完成了!”

换句话说,您可以在逻辑上将异步 I/O 请求同步完成的情况视为异步完成。它只是在你眨眼之前异步完成。