我正在使用异步I / O,因为它不会阻塞调用线程并在幕后执行线程处理。如果我在同一个Stream上调用多个异步操作(如BeginWrite()),我是否应该担心数据缓冲区内容是否混合在一起?
我们假设我想发送3个缓冲区:
Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333
我不介意缓冲区的发送顺序是否正确,所以
333333333311111111112222222222
没问题,但缓冲内容是否可能完全混合在一起?
122213121212122333313111223333
PS:我100%肯定有人已经以某种形式问过这个......
答案 0 :(得分:8)
这取决于Stream的实现。例如,套接字支持读取和写入的多个重叠请求,文件API也是如此。它们保证每个操作的一致性(没有交错内容)以及操作顺序:例如,对于套接字读取,接收的字节将被放置在发布的订单中发布的缓冲区中。如果不提供这些保证,则无法编写高性能网络应用程序,因为重叠的发送是期望的,但重叠的接收实际上必需用于高性能网络IO。许多文章都描述了这种行为,包括好的“Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports”,并在MSDN Overlapped Input/Output上有记录:
发送和接收操作都可以 重叠。接收功能 可以多次调用发布 接收缓冲区以备 传入数据和发送功能 可以多次调用队列 向上发送多个缓冲区。注意 虽然一系列重叠发送 缓冲区将按顺序发送 提供,相应的完成 适应症可能发生在不同的地方 订购。同样,在接收时 一边,缓冲区将被填充 订购它们,但是 完成指示可能发生在 不同的顺序。
毫不奇怪,同样的保证会延续到世界的管理方面,例如。 NetworkStream
课程:
读写操作即可 同时进行 NetworkStream类的实例 无需同步。 只要有一个独特的线程 用于写操作和一个 用于读取操作的唯一线程, 不会有交叉干扰 读写线程之间没有 同步是必需的。
话虽如此,在Stream上随机抛出异步读写将导致混乱很快。应用程序需要仔细协调线程提交操作的顺序,以使订单具有确定性。通常这意味着在(同步)列表中将记帐保持特别小心,以便在保持同步锁时执行异步操作调用。
最后要注意的是,所有这些异步API在调用 completion 的顺序并不保证与提交顺序相匹配时特别注意。
答案 1 :(得分:0)
不,文件流不支持多个并发IO。 Windows文件系统无法很好地处理。它几乎肯定会抛出异常。
编辑:
Synchronization and Overlapped Input and Output似乎表明文件系统将正确处理多个重叠的IO请求。我的坏。
但是,请勿尝试在FileStream
上执行并发同步写入。 那会抛出异常。