本文介绍了在多个线程的同一TCP套接字上发出阻塞write()调用是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有两个线程,T1和T2.

Let's say I have two threads, T1 and T2.

线程T1在TCP套接字S上进行阻塞的write()调用,以发送较大的字节B1缓冲区.字节B1的缓冲区很大,以至于(a)写调用块和(b)TCP必须使用多个段来发送缓冲区.

Thread T1 makes a blocking write() call on a TCP socket S to send a large buffer of bytes B1. The buffer of bytes B1 is so large that (a) the write call blocks and (b) TCP has to use multiple segments to send the buffer.

线程T2还在同一TCP套接字S上进行了阻塞的write()调用,以发送字节B2的其他大缓冲区.

Thread T2 also makes a blocking write() call on the same TCP socket S to send some other large buffer of bytes B2.

我的问题是这样

在UNIX上实施TCP能否保证B1的所有字节先于B2的所有字节发送(反之亦然)?

Does the implementation of TCP on UNIX guarantee that the all bytes of B1 will be sent before all bytes of B2 (or vice versa)?

或者TCP可以交错B1和B2的内容(例如,TCP发送一个包含B1数据的段,然后发送一个包含B2数据的段,然后又发送一个包含B1数据的段).

Or is it possible that TCP interleaves the contents of B1 and B2 (e.g. TCP sends a segment with B1 data, then a segment with B2 data, an then a segment with B1 data again).

PS-我知道这样做不是一个好主意.我正在尝试确定一些我未编写的代码是否正确.

PS - I know it is not a good idea to do this. I'm trying to determine whether or not some code which I did not write is correct.

推荐答案

尝试

TL; DR:为了编写和调试代码,除非您的目标是生命维持系统,否则假设原子性是安全的.

It Tries

TL;DR: for the purpose of writing and debugging code, it's safe to assume atomicity, unless your target is a life support system.

如果tcp套接字上的send(2)(与write(2)相同)不是原子的,则总是很糟糕.从来没有充分的理由实现非原子写入. Unix和Windows的所有版本都试图保持原子写操作,但是显然很少提供保证.

It is always going to be bad if a send(2) (same as write(2)) on a tcp socket is not atomic. There is never a good reason to implement a non-atomic write. All versions of Unix and Windows attempt to keep the write atomic, but apparently very few provide a guarantee.

已知Linux通常通常" 正确无误,但即使在最近的内核中也存在错误.它确实尝试锁定套接字,但是在某些情况下,内存分配可能会失败,并且写入将被拆分.参见此有关sendmsg 的IBM博客条目,以获取详细信息. [链接已固定.]

Linux is known to "usually" get this right but it has a bug, even in recent kernels. It does attempt to lock the socket but under certain circumstances a memory allocation can fail and a write will be split up. See this IBM blog entry on sendmsg for details. [Link fixed.]

根据这些测试,只有AIX和Solaris完全通过了线程压力测试.甚至那些系统是否都有根本没有发现的故障案例也是未知的.

According to those tests, only AIX and Solaris completely passed a thread-stress-test. It is not known if even those systems have failure cases that simply were not uncovered.


这篇关于在多个线程的同一TCP套接字上发出阻塞write()调用是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:51