6

我正在使用异步 I/O,因为它不会阻塞调用线程并在幕后进行线程处理。如果我在同一个 Stream 上调用多个异步操作,如 BeginWrite(),我是否需要担心数据缓冲区内容混合在一起?

假设我要发送 3 个缓冲区:

Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333

我不介意缓冲区是否以错误的顺序发送,所以

333333333311111111112222222222

没问题,但是缓冲区内容是否有可能完全混合在一起?

122213121212122333313111223333

PS:我100%确定有人已经以某种形式提出过这个问题......

4

2 回答 2

8

这取决于 Stream 的实现。例如,套接字支持读取和写入的多个重叠请求,文件 API 也是如此。它们保证每个操作的一致性(没有交错内容)以及操作顺序:例如对于套接字读取,接收到的字节将被放置在按发布顺序发布的缓冲区中。如果不提供这些保证,就不可能编写高性能网络应用程序,因为需要重叠发送,但实际上高性能网络 IO需要重叠接收。这种行为在许多文章中都有描述,包括好的 ole' Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports并记录在 MSDN重叠输入/输出

发送和接收操作都可以重叠。可以多次调用接收函数来发布接收缓冲区以准备传入数据,并且可以多次调用发送函数以将要发送的多个缓冲区排队。请注意,虽然将按照提供的顺序发送一系列重叠的发送缓冲区,但相应的完成指示可能会以不同的顺序出现。同样,在接收端,缓冲区将按照它们提供的顺序被填充,但完成指示可能以不同的顺序出现。

毫不奇怪,同样的保证会延续到世界的托管方,例如。NetworkStream班级:

可以在 NetworkStream 类的实例上同时执行读取和写入操作,而无需同步。只要写操作有一个唯一线程,读操作有一个唯一线程,读写线程之间就不会相互干扰,也不需要同步。

话虽如此,在 Stream 上随机进行异步读取和写入将很快导致混乱。应用程序需要仔细安排线程提交操作的顺序,以便顺序是确定的。通常这意味着将记帐保存在(同步的)列表中,并特别注意在持有同步锁的同时执行异步操作调用。

最后一点是,所有这些异步 API 都特别指出,不能保证完成顺序与提交顺序相匹配。

于 2011-05-20T21:55:04.920 回答
0

不,文件流不支持多个并发 IO。Windows 文件系统不能很好地处理。它几乎肯定会抛出异常。

编辑:

Synchronization and Overlapped Input and Output似乎表明文件系统将正确处理多个重叠的 IO 请求。我的错。

但是,不要尝试FileStream. 会引发异常。

于 2011-05-20T21:48:34.747 回答