在同一个 Stream 上启动多个异步读/写操作会损坏数据吗?

发布于 2024-11-08 22:35:33 字数 429 浏览 8 评论 0原文

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

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

Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333

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

333333333311111111112222222222

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

122213121212122333313111223333

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

I'm using asynchronous I/O because it does not block the calling thread and does the threading stuff behind the scenes. If I invoke multiple async operations like BeginWrite()'s on the same Stream, should I need to worry about that data buffer contents are mixed together?

Let's assume I want to send 3 buffers:

Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333

I don't mind if the buffers are sent in incorrect order, so

333333333311111111112222222222

is ok, but is it possible that buffer contents are got completely mixed together?

122213121212122333313111223333

PS: I'm 100% sure that someone already asked this in some form...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挥剑断情 2024-11-15 22:35:33

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

发送和接收操作都可以
被重叠。接收函数
可以多次调用来发布
接收缓冲区准备
传入数据和发送函数
可以多次调用来排队
建立多个要发送的缓冲区。笔记
虽然一系列重叠的发送
缓冲区将按顺序发送
提供,相应完成
迹象可能会出现在不同的
命令。同样,在接收
一侧,缓冲区将被填充
订购它们的供应,但是
完成指示可能会出现在
不同的顺序。

毫不奇怪,同样的保证也适用于世界的托管端,例如。 NetworkStream 类:

读写操作可以
同时执行在
NetworkStream 类的实例
无需同步。
只要有一个独特的线程
对于写操作和一个
读取操作的唯一线程,
不会有交叉干扰
读线程和写线程之间没有
需要同步。

话虽这么说,在流上随机进行异步读取和写入很快就会导致混乱。应用程序需要仔细编排线程提交操作的顺序,以便顺序具有确定性。通常,这意味着在(同步)列表中保留记帐,并在持有同步锁的同时特别小心地执行异步操作调用。

最后一点是,所有这些异步 API 在调用时都特别注意,完成的顺序不能保证与提交的顺序匹配。

It depends on the implementation of the Stream. For instance sockets support multiple overlapped requests both for read and for write, and so does the file API. They guarantee consistency of each operation (no interleaving content) and also order of operations: for instance for socket reads the bytes received will be placed in the buffers posted in the order posted. If these guarantees would not be provided it would impossible to write high performance network application, as overlapping Sends are desired but overlapping Receives are actually required for high performance network IO. This behavior is described in many articles, including good ole' Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports and is documented on MSDN Overlapped Input/Output:

Both send and receive operations can
be overlapped. The receive functions
may be invoked multiple times to post
receive buffers in preparation for
incoming data, and the send functions
may be invoked multiple times to queue
up multiple buffers to be sent. Note
that while a series of overlapped send
buffers will be sent in the order
supplied, the corresponding completion
indications may occur in a different
order. Likewise, on the receiving
side, buffers will be filled in the
order they are supplied, but
completion indications may occur in a
different order.

Not surprisingly, the same guarantees carry over to the managed side of the world, eg. the NetworkStream class:

Read and write operations can be
performed simultaneously on an
instance of the NetworkStream class
without the need for synchronization.
As long as there is one unique thread
for the write operations and one
unique thread for the read operations,
there will be no cross-interference
between read and write threads and no
synchronization is required.

That being said, throwing randomly async reads and writes on a Stream will result in chaos pretty quickly. Applications need to carefully orchestrate the order in which threads submit the operations so that the order is deterministic. Usually this means keeping accounting in a (synchronized) list with special care to do the async operation invocation while holding the synchronization lock.

One final note is that all these async APIs make a special note in calling out that the order of completion is not guaranteed to match the order of submission.

歌枕肩 2024-11-15 22:35:33

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

编辑:

同步和重叠输入和输出似乎指示文件系统将正确处理多个重叠的 IO 请求。我的不好。

但是,不要尝试对 FileStream 进行并发同步写入。 会引发异常。

No, file streams do not support multiple concurrent IOs. The Windows file system does not handle that well. It will almost certainly throw an exception.

Edit:

Synchronization and Overlapped Input and Output seems to indicate that the file system will correctly handle multiple overlapped IO requests. My bad.

Do not, however, try to do concurrent synchronous writes on a FileStream. That throws an exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文