套接字 阻塞模式

zhuyf87 2013-01-27 09:14:32
今天读《Windows 网络编程》,第5章 - Winsock IO方法。
在讲到 “套接字 阻塞模式”时,有下面一段话和代码:



这段代码的问题在于...,只有从缓冲区读回一些内容,recv才会返回...。有时会事先查看是否存在必要的数据量可读。然而,在不实际读入数据的前提下,仅仅查看数据是一种不好的编程习惯。应尽力避免。... 为避免在没有查看系统网络缓冲的情况下,由于数据的缺乏,而造成应用程序完全陷于凝固状态。一个办法是建立一个读线程、一个处理线程,两个线程共享同一数据缓冲区(用同步对象进行同步)。读线程负责读入数据,并置入共享缓冲区,当读入到计算线程所需的最少数据量之后,触发一个事件,通知处理线程开始工作。




对于分别采用读线程和处理线程这段代码来说,我没有能够理解它(与上面代码相比)的优点。
如果数据量不足,ReadThread里面的while循环就会一直recv数据,直到接收到NUM_BYTES_REQUIRED的数据量,才设置事件,此前ProcessThread将一直Wait。ProcessThread开始工作后,ReadThread由于同步对象被占用,会阻塞在EnterCriticalSection。这么处理有什么好处呢?它解决了文字中所说的“凝固状态”的问题吗?ReadThread中while循环的recv如果读不到数据,不也是一直阻塞吗?ReadThread工作的时候,ProcessThread一直在等待,也没有工作。ProcessThread工作的时候ReadThread再等待同步对象,也没有继续recv。

请大家给小弟解惑。谢谢。-_-
...全文
335 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
mhhaifeng 2013-01-31
  • 打赏
  • 举报
回复
不用 SetEvent 把ProcessThread 函数替换到SetEvent位置 去掉 EnterCriticalSection相关内容 会有什么问题?
qzjzs 2013-01-30
  • 打赏
  • 举报
回复
recv函数会阻塞的
  • 打赏
  • 举报
回复
首先阻塞阻塞的是线程函数等完成相关事情才返回线程比如收到数据之前这个线程干不了任何事情收到数据之后这个线程继续等待下一次接收,上边描述的主要还有线程间通讯。。。
zhuyf87 2013-01-28
  • 打赏
  • 举报
回复
引用 4 楼 c1997sdn 的回复:
你想只创建一个线程,也是可以的。 分为两个线程来处理,我个人理解的好处是, 这样方便以后扩展,可以在计算线程里做些别的事情。 比如说如果不想读线程recv无限阻塞等待下去, 就可以在计算线程的WaitForSingleObject中设置超时时间。
感谢回帖。-_-
zhuyf87 2013-01-27
  • 打赏
  • 举报
回复
引用 5 楼 stjay 的回复:
猜不到作者的想法,估计是 这是将IO收发(通讯)和数据处理(业务)分离 这里为了可以一边recv数据,一边处理,有时处理数据比较耗时,单线程会影响recv 不一定是为了防止阻塞主线程 这重模型是大规模、高性能服务器普遍的设计方案
看代码的写法应该不会是为了“可以一边recv数据,一边处理,有时处理数据比较耗时,单线程会影响recv” 因为ReadThread和ProcessThread共同处理一个缓冲区,并使用了CRITICAL_SECTION进行同步。 在ProcessThread工作的时候,ReadThread是无法recv数据的。
stjay 2013-01-27
  • 打赏
  • 举报
回复
猜不到作者的想法,估计是 这是将IO收发(通讯)和数据处理(业务)分离 这里为了可以一边recv数据,一边处理,有时处理数据比较耗时,单线程会影响recv 不一定是为了防止阻塞主线程 这重模型是大规模、高性能服务器普遍的设计方案
无言猪 2013-01-27
  • 打赏
  • 举报
回复
引用 1 楼 zhuyf87 的回复:
饿。难道作者的意思是,最上面的代码是放到主线程里的,recv会阻塞主线程。整个程序就“凝固”了? 而后面单独建立两个线程,是放置阻塞主线程的?
完全正确!
zhuyf87 2013-01-27
  • 打赏
  • 举报
回复
饿。难道作者的意思是,最上面的代码是放到主线程里的,recv会阻塞主线程。整个程序就“凝固”了? 而后面单独建立两个线程,是放置阻塞主线程的?
c1997sdn 2013-01-27
  • 打赏
  • 举报
回复
你想只创建一个线程,也是可以的。 分为两个线程来处理,我个人理解的好处是, 这样方便以后扩展,可以在计算线程里做些别的事情。 比如说如果不想读线程recv无限阻塞等待下去, 就可以在计算线程的WaitForSingleObject中设置超时时间。
zhuyf87 2013-01-27
  • 打赏
  • 举报
回复
引用 2 楼 lostying 的回复:
引用 1 楼 zhuyf87 的回复:饿。难道作者的意思是,最上面的代码是放到主线程里的,recv会阻塞主线程。整个程序就“凝固”了? 而后面单独建立两个线程,是放置阻塞主线程的? 完全正确!
那分为两个线程,ReadThread和ProcessThread的好处是什么呢? 为了防止阻塞主线程,我也可以只创建一个线程,比如叫做ReadAndProcessThread。 在ReadAndProcessThread线程函数里先recv再处理。

18,363

社区成员

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

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