当两个线程尝试写入相同的TCP套接字simultaneouslu时出现同步问题

我有20个线程一次在单个TCP套接字上发送数据,并接收数据。 当我运行我的应用程序,我没有看到任何同步问题,但根据我的理解,可能会有一些问题,当两个线程同时尝试写入到TCP套接字或当一个线程正在写而其他正在读取。

如果我的理解是正确的,为什么我不面对任何错误?

有时候,在过马路之前,如果你看不到两条路,你还是会安全地到达街道的另一边。 这并不意味着你每次都能成功地运行。

这是事情,你说“你看不到任何同步问题”,但这只是因为它恰好做你想做的事情。 翻转这个 – 你没有看到任何同步问题的原因是因为你碰巧想要做它发生的事情。 有人希望它做别的事情看到同样的代码同步问题。

换句话说,你翻转了一个可能出现正面或反面的硬币。 你以为它不会得到保证,所以你期望它会出现。 它出现了。 没有什么神秘的 – 解释是你期望它发生了什么事情。 如果你期望别的东西,即使它做了同样的事情,它也不会做到你所期望的。

首先,每个套接字的发送和接收流是独立的。 一个线程在另一个线程接收时应该没有问题。

如果多个线程尝试写入一个套接字,则通常情况下,该行为是未定义的。 在实践中,来自其中一个线程的写入调用将首先进入TCP堆栈状态机的锁定,防止任何其他线程进入,写入其数据,释放锁定并退出堆栈,从而允许来自其他线程的写入调用线程继续。 这将允许单个写入调用序列化。 如果你的协议实现可以用一个写呼叫发送所有的PDU,那么很好。 如果一个PDU需要多个写入调用,那么当多个线程的写入调用得到交错时,您的传出PDU就会被分割。

从多个线程接收调用到一个套接字只是…东西。 即使堆栈内部同步一次只允许每个套接字接收一次调用,TCP的流式性质也将在整个线程中以伪随意的方式将接收到的数据分割开来。 只是不要这样做,这太疯狂了。

TCP已经有一个多路复用数据流的机制 – 多个套接字。 你应该正确使用它们。

如果您需要在一个套接字上复用数据流,则应该在TCP上添加一个数据路由协议,并在一个接收线程中实现此协议。 这个线程可以保持虚拟连接的列表,以及来自其他线程的服务流/消息请求。