Ays*_*yse 1 c sockets windows network-programming tcp
我有20个线程,一次在单个tcp套接字上发送数据并接收数据.当我运行我的应用程序时,我没有看到任何同步问题,但根据我的理解,当两个线程同时尝试写入tcp套接字或当一个线程正在写入而其他线程正在读取时,可能会出现一些问题.
如果我的理解是正确的,为什么我不会面临任何错误?
有时当你在过马路之前不看双向时,你仍然可以安全地到达街道的另一边.这并不意味着每次这样做都会成功.
这就是问题,你说"你没有看到任何同步问题",但这只是因为碰巧做了你想做的事情.翻转这个 - 你没有看到任何同步问题的原因是因为你碰巧希望它做它碰巧做的事情.期望它做其他事情的人会看到同一代码的同步问题.
换句话说,你翻转了一个可能出现在头部或尾部的硬币.你知道它不会得到保证.它出现了头脑.没有什么神秘感 - 解释是你期望它发生了什么.如果你期待别的东西,即使它做了同样的事情,它也不会做你想象的.
首先,每个套接字的发送和接收流是独立的。一个线程发送而另一个线程接收时应该没有问题。
如果多个线程试图写入一个套接字,则行为通常是未定义的。实际上,来自其中一个线程的写调用将首先进入TCP堆栈状态机中的锁,从而防止任何其他线程进入,写入其数据,释放该锁并退出堆栈,因此允许来自其他线程的写调用线程继续。这样可以序列化单个写调用。如果您的协议实现可以通过一个写调用发送所有PDU,则可以。如果PDU需要多个写入调用,则随着来自多个线程的写入调用被交错,您的传出PDU可以被分割。
从多个线程到一个套接字的接收调用仅仅是……某件事。即使堆栈内部同步一次只允许每个套接字一个接收调用,TCP的流式传输性质也肯定会以伪任意方式跨线程拆分接收到的数据。只是不做,这很疯狂。
TCP已经具有用于复用数据流的机制-多个套接字。您应该正确使用它们。
如果需要跨一个套接字多路复用数据流,则应在TCP之上添加数据路由协议,并仅在一个接收线程中实现此协议。该线程可以保留虚拟连接的列表,因此可以提供其他线程的服务流/消息请求。