2013-07-12 38 views
1

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

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

+1

@DavidSchwartz是的,我错过了问题的第一部分,并回答了关于一个读者+一个作家的位。误导评论已删除。 – simonc

+0

尝试使用更多线程查看差异,可能会看到一些差异。 – pradipta

+0

+1的建议,我会试一试:) – Ayse

回答

6

有时候,如果在过马路前你没有看到两条路,你仍然可以安全地到达街道的另一边。这并不意味着每次你做它都会成功。

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

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

+0

+1,谢谢你的有趣的解释。 – Ayse

4

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

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

从多个线程接收来自一个套接字的调用只是...某事。即使堆栈内部同步一次只允许每个套接字一次接收调用,TCP的流式性质也必然会在线程中以伪随机方式分割接收到的数据。只是不要这样做,这太疯狂了。

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

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

相关问题