关于TCP/UDP 是否多线程安全_2019.12.27

对于 UDP,多线程读写同一个 socket 不用加锁,不过更好的做法是每个线程有自己的 socket,避免 contention,可以用 SO_REUSEPORT 来实现这一点。

对于 TCP,通常多线程读写同一个 socket 是错误的设计,因为有 short write 的可能。假如你加锁,而又发生 short write,你是不是要一直等到整条消息发送完才解锁(无论阻塞IO还是非阻塞IO)?如果这样,你的临界区长度由对方什么时候接收数据来决定,一个慢的 peer 就把你的程序搞死了。

总结:对于 UDP,加锁是多余的;对于 TCP,加锁是错误的。

 

解答③:

对于TCP,正确的做法是,创建一个单独的发送线程,让发送线程统一发送数据。例如你的工作线程池处理完了业务task,你把需要回复的包封装成一个发送task,包含发送套接字和消息,丢给发送线程就行了。

对于UDP,它是面向报文的是一个完整的报文接一个完整的报文的,不需要加锁,在UNP中也提到过一个发送就是一个原子操作。其实我们从UDP的接收都可以看的出来,UDP接收的时候需要设置接收缓冲大于报文大小,并且每次从接收缓冲都是只能取回一个完整的包,不需要处理粘包,半包。首先是说了UDP协议栈会在发送的时候分片,到了接收重组,每次组好了完整的包就丢给用户,不完整就丢掉。其次说明了协议栈是以报文整个的形式来传递,所以是原子操作,“线程安全”。

 

单例模式:

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值