【问题标题】:Synchronization issues when two threads try to write to same tcp socket simultaneouslu两个线程尝试同时写入同一个 tcp 套接字时的同步问题
【发布时间】:2013-07-10 15:27:07
【问题描述】:

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

如果我的理解是正确的,为什么我不会遇到任何错误?

【问题讨论】:

  • @DavidSchwartz 是的,我错过了问题的第一部分,并回答了关于一位读者 + 一位作者的问题。误导性评论已删除。
  • 尝试使用更多线程来查看差异,也许您可​​以看到一些差异。
  • +1 的建议,我会试试看 :)

标签: c windows sockets tcp network-programming


【解决方案1】:

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

事情是这样的,你说“你没有看到任何同步问题”,但这只是因为它恰好做了你想让它做的事情。反过来——你看不到任何同步问题的原因是你碰巧希望它做它碰巧做的事情。期望它执行其他操作的人看到使用相同代码的同步问题。

换句话说,你掷的硬币可能正面或反面。你期望它会出现,知道它不能保证。它出现了。这并不神秘——解释是你预料到它会发生什么。如果你期待别的东西,即使它做了同样的事情,它也不会达到你的预期。

【讨论】:

    【解决方案2】:

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

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

    从多个线程对一个套接字进行接收调用只是……一些东西。即使堆栈内部同步一次只允许每个套接字一次接收调用,TCP 的流传输性质肯定会在线程之间以伪任意方式拆分接收到的数据。不要这样做,这太疯狂了。

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

    如果您需要在一个套接字上多路复用数据流,您应该在 TCP 之上添加一个数据路由协议,并在一个接收线程中实现该协议。该线程可以保存一个虚拟连接列表,从而为其他线程的流/消息请求提供服务。

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 1970-01-01
      • 2014-08-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-20
      • 2018-11-24
      • 2016-11-01
      • 1970-01-01
      相关资源
      最近更新 更多