Select IO模型 + 线程池收数据的问题(坐等结贴)

96掌门师兄 2013-01-16 04:53:14
主线程循环 select IO模型将所有的连接上的socket进行可读性检查,当发现可读时,将可读的socket传递给线程池,让线程池收数据。
但是这是出现了一个问题,就是线程还没有将数据收完(缓冲区还有数据),主线程中下一次select检测又来了,又发现缓冲区有数据可读,有塞一个任务给线程池,这样导致一包数据,可能会产生过个线程去收。该如何有效的解决这个问题呢? 如何加锁?
...全文
541 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
marlboro_1999 2014-07-28
  • 打赏
  • 举报
回复
LZ你理解错了。select 模型对套接字的可读性进行轮询,select 函数返回之后会标识出有多少个套接字上面有数据到来了而已,但这时数据已经到达系统的底层,这时你只需要使用对应的套接字调用recv函数去把数据拿出来就可以,不同的套接字调用recv函数时只会将属于它自己的那部分数据拿出来,而不是你理解的会拿到别人的数据。 你说的线程池无非就是当同时有多少个套接字上面有数据到来时就开多少个线程,然后线程函数里面用相应的套接字调用recv函数去拿数据。但即使这样你拿到的数据也仅仅是属于特定的那个套接字的。
Kaile 2013-01-29
  • 打赏
  • 举报
回复
微软太抠门,机票钱都不出,没诚意
傻X 2013-01-29
  • 打赏
  • 举报
回复
引用 29 楼 xiaoxiaoyu85 的回复:
引用 25 楼 tiger9991 的回复:引用 23 楼 xiaoxiaoyu85 的回复: 引用 15 楼 tiger9991 的回复:epoll 网游用这个 你得了MVP啊?呵呵,恭喜啊。。。 还不是靠兄弟们的捧场么。 好像是有机会去美国吧? 哈哈,真爽。
有个MVP全球峰会,自己买机票搞签证,Microsoft包5天4夜食宿,我没去啊。 下次有空了当旅游再去吧。
96掌门师兄 2013-01-29
  • 打赏
  • 举报
回复
a ???那是郁闷的很啊,应该包机票才对嘛。。。
96掌门师兄 2013-01-28
  • 打赏
  • 举报
回复
引用 25 楼 tiger9991 的回复:
引用 23 楼 xiaoxiaoyu85 的回复: 引用 15 楼 tiger9991 的回复:epoll 网游用这个 你得了MVP啊?呵呵,恭喜啊。。。 还不是靠兄弟们的捧场么。
好像是有机会去美国吧? 哈哈,真爽。
chaoyuu 2013-01-26
  • 打赏
  • 举报
回复
引用 3 楼 yaozhiyong110 的回复:
select不是这样玩的...
select应该是怎样玩?
shiter 2013-01-25
  • 打赏
  • 举报
回复
windows下面,用什么实习这种东西?
zhangyihu321 2013-01-25
  • 打赏
  • 举报
回复
在线程内部检查比较好
傻X 2013-01-24
  • 打赏
  • 举报
回复
引用 23 楼 xiaoxiaoyu85 的回复:
引用 15 楼 tiger9991 的回复:epoll 网游用这个 你得了MVP啊?呵呵,恭喜啊。。。
还不是靠兄弟们的捧场么。
Joseph-Growth 2013-01-24
  • 打赏
  • 举报
回复
我觉的select真不是这样用的。每次select处理后,该套接字应该已经从select里面剥离出去了。需要再次添加进来才可以。 这个时间,该套接字的缓冲区数据应该你能够拿完了。下次你需要用新的缓冲区来收数据了。
96掌门师兄 2013-01-24
  • 打赏
  • 举报
回复
引用 15 楼 tiger9991 的回复:
epoll 网游用这个
你得了MVP啊?呵呵,恭喜啊。。。
96掌门师兄 2013-01-24
  • 打赏
  • 举报
回复
引用 21 楼 ls443085074 的回复:
搞两个队列撒,一个检测socket队列A,一个数据接收队列B,检测是把A中有数据的socket丢到B里面去,同时送线程收数据,线程收完数据负责把socket从B里面去除,在放回到A,这样就不存在你说的问题了撒,你只需要做好A B的放入放出互斥
差不多就是这么实现的了。。
ls443085074 2013-01-24
  • 打赏
  • 举报
回复
搞两个队列撒,一个检测socket队列A,一个数据接收队列B,检测是把A中有数据的socket丢到B里面去,同时送线程收数据,线程收完数据负责把socket从B里面去除,在放回到A,这样就不存在你说的问题了撒,你只需要做好A B的放入放出互斥
jwybobo2007 2013-01-24
  • 打赏
  • 举报
回复
windows下的话,可以开N个线程,每个线程单独执行select并负责一组accept到的socket(通常最大值64个)
这不是鸭头 2013-01-17
  • 打赏
  • 举报
回复
只要是数据没有读完,select都会有返回的。
zzz_zou 2013-01-17
  • 打赏
  • 举报
回复
感觉是没用好,你select发现可读,直接去读,然后将数据塞入缓冲区(每个socket一个缓冲区),对这个数据的处理可以是另外开启线程,也可以是你即时处理(如果不耗时),只需要一个线程一直select就好了,当连接断开时,干掉对应的缓冲区不就可以了?
Squall_zy 2013-01-17
  • 打赏
  • 举报
回复
引用 14 楼 xiaoxiaoyu85 的回复:
那这种线程池的服务端程序应该用什么模型呢?
IOCP就是啊。IOCP中,为了节省线程切换带来的资源消耗,采用LIFO的调度。
傻X 2013-01-16
  • 打赏
  • 举报
回复
另外,其实select也可以多线程的,只不过多线程是分配socket的时候。多个socket多个线程处理。
傻X 2013-01-16
  • 打赏
  • 举报
回复
epoll 网游用这个
96掌门师兄 2013-01-16
  • 打赏
  • 举报
回复
引用 13 楼 Squall_zy 的回复:
每种IO模式都有自己的使用方式。 select模型只适合单个线程,这由select函数本身的特性决定了,并且读写操作就该紧随其后。这是正确的使用方式。 如果非要用多个线程去处理,不单效率没有提升,反而会带来其他的麻烦,如同步问题、处理次序问题等。
那这种线程池的服务端程序应该用什么模型呢?
加载更多回复(13)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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