请教:多线程同时写socket是否需要加锁



第一种可以,因为Socket是双工的


多线程读写同一Socket的话基本上是会出问题的
想要不出问题的话,除非你的多个线程作用是一样的








在TCP/TP卷2中有这样的结构体
struct sockbuf{


short sb_flags;
..........
}so_recv,so_snd;
其中flag 有这几种标志:
SB_LOCK;一个进程已经锁定了插口缓存
SB_WANT;一个进程正在等待给插口缓存加锁.


还有些宏和函数来管理插口的发送缓存和接收缓存
sblock,  sbunlock, sbwait(page 388,389)
也就是说感觉socket内部其实已经考虑到了这点,我们应用的时候是否只需要
一些操着比如设置一些标志位或者一些宏?






继续翻了下send 的实现,
发现了有如下代码:


if(error = sblock(&so->so_snd, SBLOCKWAIT(flag)))   
         goto  out;
do{


.......


}


函数在发送的时候,首先会对缓存加锁.通过加锁确保多个进程按序互斥访问插口缓存.(tcp/ip 卷2, page 394,395)
也就是说其实系统已经帮我们做好这些了.






多线程写socket应该要加锁,而且要保证返回值等于要发送的数据长度或出错后才能解锁。虽然内核在写一个文件时可能会


自动加锁,但是如果socket缓冲区不足以容纳下用户的所有数据的话,线程要进入睡眠状态,这时系统是否会解锁跟实现有


关吧






应该对socket加锁。 尤其是对非阻塞的socket,底层对缓冲区加锁并不能解决数据交错的问题。




我想flw2 是想让你在 send_n 的时候加锁
虽然系统send 是原子的..但不保证 send_n是原子的..所以要加锁以保证 线程A send_n完后.
线程B再send_n .




我刚学网络编程的时候也傻到给socket加锁,后来用代码验证是不需要加锁的:lol:




一般都是多个工作线程把需要发送的数据写到一个加锁的缓冲区中,然后另外一个线程单独进行收发。多个线程直接写


socket还真没这么做过。我觉得应该是加锁处理,并且需要判断已发送字节数等于发送字节数才成。




需要加锁。 除非单一线程发送




把这个贴子再顶起来,因为我今天刚好碰到了这个问题。用多个线程写一个套接口,读据在应用层肯定是混在一起的,比如


线程t1要写100个'a',线程t2要写100个'b',那么实际上对方接收到的数据是a、b混杂的,这就一点意义也没有了。有人说


write是原子的,但是我们一般用的都是writen吧,很少调用一次write不管结果如何都返回的。可以结贴了吧,呵呵


对SOCKET的写操作从用户的角度并不是原子的,因为如果一次发送1M数据,肯定不是原子的.至于一次发送多少会是原子的,好


像没有明确的说法 (最好不要去做原子性的假设) (和MTU是没有关系的,那是底层的分包)




归根结底好像有两个结论:


1.避免多个线程同时对一个socket进行操作。


2.如果是在无法避免上述情况,则应该加锁。


是否正确?






如果需要多个线程同时读访问或写访问同一个tcp socket, 那多半是程序设计上出了问题。


对于tcp的传输,都是要用应用层的协议保证接收方能解释对方发送过来的数据,这样,至少要保证一块数据是一个完整的协


议包。


如果是多个线程同时写socket,那么在临界区里工作的线程为了保证数据包的完整发送,必须循环发送等待,直到数据都发


送到系统缓冲区才能离开临界区。
而这样就导致socket的行为与阻塞方式发送无异,发送效率因此而被限制。


我觉得一个好的tcp socket处理框架,应该是只有一个线程来负责数据的收发,从而避免那些无穷无尽的同步问题。






如果需要多个线程同时读访问或写访问同一个tcp socket, 那多半是程序设计上出了问题。


对于tcp的传输,都是要用应用层的协议保证接收方能解释对方发送过来的数据,这样,至少要保证一块数据是一个完整的协


议 ... 


正解!






其实这种情况很常见,为什么说是设计的问题?
举个例子:
一个porxy服务器,一边连接客户端,一边连接服务端的80端口.对于每个客户的连接处理为一个线程,收到客户消息转发到服务


器.




PROXY, 对于CLIENT的一个连接,就建立一个到SERVER的连接.
所以,混杂的情况是没有的.


不同的FLOW的包混在一个LINK中是设计出问题了.






如果需要多个线程同时读访问或写访问同一个tcp socket, 那多半是程序设计上出了问题。


对于tcp的传输,都 ...


同意
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值