代码之家  ›  专栏  ›  技术社区  ›  Bruno Rijsman

在同一个TCP套接字上从多个线程发出blocking write()调用是否安全?

  •  10
  • Bruno Rijsman  · 技术社区  · 16 年前

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

    线程T1对TCP套接字进行blocking write()调用,以发送字节b1的大缓冲区。字节b1的缓冲区太大,以至于(a)写调用块和(b)TCP必须使用多个段来发送缓冲区。

    线程t2还对同一个tcp套接字进行blocking write()调用,以发送字节b2的其他大缓冲区。

    我的问题是:

    在Unix上实现TCP是否保证b1的所有字节将在b2的所有字节之前发送(反之亦然)?

    或者,TCP是否可能交错b1和b2的内容(例如,TCP发送一个包含b1数据的段,然后发送一个包含b2数据的段,然后再发送一个包含b1数据的段)。

    我知道这样做不是个好主意。我正在尝试确定一些我没有写的代码是否正确。

    1 回复  |  直到 9 年前
        1
  •  11
  •   DigitalRoss    9 年前

    它尝试

    DR: 为了编写和调试代码,假设原子性是安全的,除非您的目标是生命支持系统。


    如果 send(2) (同) write(2) )在TCP套接字上不是原子的。实现非原子写从来没有好的理由。Unix和Windows的所有版本都试图保持写原子性,但显然很少提供保证。

    Linux众所周知 “通常” 1。 正确地说,但它有一个错误,即使是在最近的内核中。它确实试图锁定套接字,但在某些情况下,内存分配可能会失败,写入将被拆分。见 this IBM blog entry on sendmsg 详情。 [链接固定]

    根据这些测试,只有AIX和Solaris完全通过了线程压力测试。目前还不清楚,即使是那些系统,是否也存在根本没有发现的故障案例。


    1。tl;dr:几乎总是,也就是说,除非出现某种错误。