请各位大牛帮忙解决,Windows下udp多线程问题

风涛hit 2016-05-31 11:25:51
最近项目需要,在做udp性能测试。但是测试过程发现一个问题,还没弄太明白,希望各位大牛帮助解决。
问题描述:两台计算机,通过千兆网卡通信,使用udp编程,一台做客户端,一台做服务端。服务端采用多线程模式编写,每个线程创建都会创建属于自己的socket,这些socket都绑定到同一IP的不同端口下,并在此socket上等待接收数据。客户端同样采用多线程模式,每个线程开辟对应服务程序各线程的socket,通过此socket发送数据。经过测试,当使用单线程运行时,服务端与客户端能正常收发数据,双方速度均在130Mbps左右,基本无丢包。但是当使用2个线程或更多线程进行数据收发时,例如使用两个线程进行收发,发送线程速度依然130Mbps,但是接收线程丢包严重,导致速度下滑厉害,有时才几兆bit每秒。
  但是如果同时打开2个服务程序及客户端程序进行数据收发,每个程序中使用1个线程进行工作,则每个服务程序的接收速度与客户端的发送速度基本一致,大概130Mbps,且都没有丢包。两个服务程序的接收速度和为260Mbps。
  现在不清楚的是为什么在多线程情况下跟多进程情况下有这么大的差距,原因为何?
  先谢谢各位了,这几天一直没弄明白,希望大家能提供一些有用的思路。
...全文
479 3 打赏 收藏 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
风涛hit 2016-06-03
  • 打赏
  • 举报
回复
不过问题确实解决了,之前各线程调用sendto时使用的发送缓存是由进程创建的,所以各线程是共享该发送缓存的,因为不改变发送数据,而且为了提高线程的发送速度,取消了对共享发送缓存区的加锁。代码运行的结果就是之前描述的那样。 昨天重新整理了代码,为了方便,各个线程独立创建自己的发送缓存,之后再运行程序,就没有之前的问题了。但是具体原因还没有想的很明白,但是可以肯定的是socket使用sendto进行数据发送时会检查发送缓存,因为传给sendto的是缓存地址,这个地址需要映射到内核中,驱动执行发送操作时可能是以直接方式进行的,这样就需要在内核中锁定用户缓冲区的地址,导致当其他线程也进行发送时,不能访问该用户缓冲地址,导致发送延时,造成对端接收超时。 产生了上述的问题。 不过这也只是我自己的想法,还没有更深入的研究udp的内部实现。
风涛hit 2016-06-03
  • 打赏
  • 举报
回复
谢谢您的回复。 但是还是有点不太明白,正常确实应该对线程使用的共享数据缓存进行加锁,进行同步,但是,我的每个线程只是把缓存里的数据给sendto发出去,而且不加锁应该可以发挥socket最大的发送速度,因为取消了线程同步。而且接收端不会对接收的数据进行检查,只要接收到报文数据就行。为什么会造成问题呢?
赵4老师 2016-06-02
  • 打赏
  • 举报
回复
多线程环境下该加锁的地方漏加锁。

4,172

社区成员

发帖
与我相关
我的任务
社区描述
Windows专区 一般软件使用
社区管理员
  • 一般软件使用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧