免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: houhulou
打印 上一主题 下一主题

[C++] SOCKET多线程向同一SOCKET发送数据,数据会出现互相重叠坏掉吗 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2010-01-28 09:30 |只看该作者
原帖由 houhulou 于 2010-1-28 09:01 发表

内核栈, 既然是栈了 那就是内核函数里自己开辟的, 就算一次没有COPY进去, 中间有其他线程调用了, 数据也是放在两个内核栈里 ,这里会出现交叉吗?


你搞混了进程/线程的内核栈 和 内核协议栈。
前者是一个进程/线程一个,独立的,尺寸很小的,比如8K. 放不了什么东西。仅仅为了内核的函数运行和很少的内核栈变量。用户数据从来不放到这里。

内核协议栈可以理解为是一个。

论坛徽章:
0
22 [报告]
发表于 2010-01-28 09:36 |只看该作者
原帖由 思一克 于 2010-1-28 09:27 发表


TCP一次发送100字节,对方一定是顺序和连续的,就是B0,B1,B2,......B99是连续的,顺序不会乱,中间也不可能有其它插入进来。
但对方不一定确保是一次性接收到的。比如可能分3次。B0,B1-----B97是一次,第二 ...


对方一定会是顺序的这个是肯定的,但连续的不一定,对于阻塞的tcp socket, 你两个线程都在不停的写,你不能保证其中一个线程由于内核传冲区不足在睡眠过程中其它线程也来write()了一把

论坛徽章:
0
23 [报告]
发表于 2010-01-28 09:42 |只看该作者
原帖由 学与思 于 2010-1-28 09:36 发表


对方一定会是顺序的这个是肯定的,但连续的不一定,对于阻塞的tcp socket, 你两个线程都在不停的写,你不能保证其中一个线程由于内核传冲区不足在睡眠过程中其它线程也来write()了一把


我知道你的意思。
就是接收方可能是收很多次才收到这100个字节的。是这样的。

论坛徽章:
0
24 [报告]
发表于 2010-01-28 09:50 |只看该作者
原帖由 思一克 于 2010-1-28 09:42 发表


我知道你的意思。
就是接收方可能是收很多次才收到这100个字节的。是这样的。


我还真不是你说的那个意思哈

如果只有一个线程write(sock, ),返回说成功写了100bytes,毫无疑问,对方收到的也一定是连续的,但有两个线程:

-------------------------------------------------------------------------------------------------------------->time
thread1 write() copy 50bytes进入内核缓冲区---> 睡                                 眠---再copy 50bytes-->
                                                                              thread2 write() return 5bytes----------->

能不能保证thread2写入的5bytes不会插入thread1前面写入的50bytes后面?

[ 本帖最后由 学与思 于 2010-1-28 09:52 编辑 ]

论坛徽章:
0
25 [报告]
发表于 2010-01-28 09:51 |只看该作者
原帖由 学与思 于 2010-1-28 09:50 发表


我还真不是你说的那个意思哈

如果只有一个线程write(sock, ),返回说成功写了100bytes,毫无疑问,对方收到的也一定是连续的,但有两个线程:

---------------------------------------------------- ...

两个线程当然可能要乱了。一个线程的数据块被别人的数据插入了。

论坛徽章:
0
26 [报告]
发表于 2010-01-29 08:48 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
27 [报告]
发表于 2010-01-29 09:00 |只看该作者
原帖由 学与思 于 2010-1-28 09:50 发表


我还真不是你说的那个意思哈

如果只有一个线程write(sock, ),返回说成功写了100bytes,毫无疑问,对方收到的也一定是连续的,但有两个线程:

---------------------------------------------------- ...


这个以前实际测试过,系统是SUSE9和XP,多线程没有出现过5字节插到中间的问题,甚至send的返回值也只有两种情况,要么等于指定的发送量,要么小于等于0,也就是说没有遇到发送掉一半的情况就返回的情况。我个人猜测操作系统在send内部已经加了互斥锁了,send函数不会中道返回应该也是为此考虑的(如果会中道返回,那么两个线程循环send的顺序就不可保证)。不过可惜的是我找不到什么相关文档证明这一点猜测。后来还是把发送全部交给同一个线程去做了。

论坛徽章:
0
28 [报告]
发表于 2010-01-29 09:12 |只看该作者
原帖由 w_anthony 于 2010-1-29 09:00 发表


这个以前实际测试过,系统是SUSE9和XP,多线程没有出现过5字节插到中间的问题,甚至send的返回值也只有两种情况,要么等于指定的发送量,要么小于等于0,也就是说没有遇到发送掉一半的情况就返回的情况。我 ...


send不中间返回也不保证是原子的。
SEND一大块数据(比如128M), send在内核中会申请内存(内核协议栈用),SEND了一部分后申请内存会转等待,等其他SEND用的内存释放。而该等待就是线程/进程的切换。

SEND返回正常不保证数据到了对端,而是保证所有数据都被本机内核处理过了。

论坛徽章:
0
29 [报告]
发表于 2010-01-29 09:12 |只看该作者
实际是流式SOCKET(TCP)即使建立一个2端的数据字节管道。一个管道用5元组(IP0, PORT0, IP1, PORT1, TCP不必要)表示的。
2个线程进程同时往同一个管道里放水,水有可能混合。

文件系统不许这样。
pipe仅仅保证在多线程发送小于pipe原子数据尺寸的数据时候的原子性。

[ 本帖最后由 思一克 于 2010-1-29 09:22 编辑 ]

论坛徽章:
0
30 [报告]
发表于 2010-01-29 09:26 |只看该作者
原帖由 思一克 于 2010-1-29 09:12 发表
实际是流式SOCKET(TCP)即使建立一个2端的数据字节管道。一个管道用5元组(IP0, PORT0, IP1, PORT1, TCP不必要)表示的。
2个线程进程同时往同一个管道里放水,水有可能混合。

文件系统不许这样。
pipe仅仅 ...



嗯,应该是这样的吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP