首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 软件时空 > 软件相关 > 关于阻塞(blocking)的概念和select()函数
【标  题】:关于阻塞(blocking)的概念和select()函数
【关键字】:blocking,select
【来  源】:http://www.cublog.cn/u/11557/showart.php?id=104967

关于阻塞(blocking)的概念和select()函数

当服务器运行到accept语句时,而没有客户连接服务请求到来,那么会发生什么情况?这时服务器就会停止在accept语句上等待连接服务请求的到来;同样,当程序运行到接收数据语句时,如果没有数据可以读取,则程序同样会停止在接收语句上。这种情况称为blocking。但如果你希望服务器仅仅注意检查是否有客户在等待连接,有就接受连接;否则就继续做其他事情,则可以通过将Socke设置为非阻塞方式来实现:非阻塞socket在没有客户在等待时就使accept调用立即返回

  i nclude unistd.h

  i nclude fcntl.h

  . . . . sockfd = socket(AF_INET,SOCK_STREAM,0);

  fcntl(sockfd,F_SETFL,O_NONBLOCK) . . . . .

  通过设置socket非阻塞方式,可以实现“轮询”若干Socket。当企图从一个没有数据等待处理的非阻塞Socket读入数据时,函数将立即返回,并且返回值置为-1,并且errno置为EWOULDBLOCK。但是这种“轮询”会使CPU处于忙等待方式,从而降低性能。考虑到这种情况,假设你希望服务器监听连接服务请求的同时 从已经建立的连接读取数据,你也许会想到用一个accept语句和多个recv()语句,但是由于acceptrecv都是会阻塞的,所以这个想法显然不会成功。

  调用非阻塞的socket会大大地浪费系统资源。而调用select()会有效地解决这个问题,它允许你把进程本身挂起来(?),而同时使系统内核监听所要求的一组文件描述符的任何活动,只要确认在任何被监控的文件描述符上出现活动,select()调用将返回指示该文件描述符已准备好的信息,从而实现了为进程选出随机的变化,而不必由进程本身对输入进行测试而浪费CPU开销。Select函数原型为:

  int select(int numfds,fd_set *readfds,fd_set *writefdsfd_set *ex ceptfds,struct timeval *timeout);

  其中readfdswritefdsexceptfds分别是被select()监视的读、写和异常处理的文件描述符集合。如果你希望确定是否可以从标准输入和某个socket描述符读取数据,你只需要将标准输入的文件描述符0和相应的sockdtfd加入到readfds集合中;numfds的值是需要检查的号码最高的文件描述符加1,这个例子中numfds的值应为sockfd+1;当select返回时,readfds将被修改,指示某个文件描述符已经准备被读取,你可以通过FD_ISSSET()来测试。为了实现fd_set中对应的文描述符的设置、复位和测试,它提供了一组宏:

  FD_ZERO(fd_set *set)----清除一个文件描述符集;

  FD_SET(int fd,fd_set *set)----将一个文件描述符加入文件描述符集中;

  FD_CLR(int fd,fd_set *set)----将一个文件描述符从文件描述符集中清除

  FD_ISSET(int fd,fd_set *set)----试判断是否文件描述符被置位。

  Timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout长时间后没有文件描述符准备好即返回。struct timeval数据结构为:

  struct timeval {

   int tv_sec; /* seconds */

   int tv_usec; /* microseconds */

  };

  我们通过程序3来说明:

  i nclude sys/time.h

  i nclude sys/types.h

  i nclude unistd.h

  #define STDIN 0 /*标准输入文件描述符*/

  main()

  {

   struct timeval tv;

   fd_set readfds;

   tv.tv_sec = 2;

   tv.tv_usec = 500000;//2.5sec

   FD_ZERO(&readfds);

   FD_SET(STDIN(?),&readfds);

   /* 这里不关心写文件和异常处理文件描述符集合 */

   select(STDIN+1 &readfds NULL NULL &tv);

if (FD_ISSET(STDIN &readfds))

printf("A key was pressed! ");

else

printf("Timed out. ");

  }

  (程序3

  select()在被监视端口等待2.5秒钟以后,就从select返回

 

汇编(二十九)——重复汇编和条件汇编:【上一篇】
Windows Communication Foundation之旅(Part Four):【下一篇】
【相关文章】
  • Eclipse Tips: Selection Service
  • 如何定义Select下拉框的边框颜色和滚动条样式
  • JS的Select排序类
  • 学习JS的作品-----N级的联动Select下拉框
  • select和option标签
  • select()用法
  • dataTable +selectOneRadio
  • dataTable中selectOneRadio传递多参数
  • dataTable和selectBooleanCheckbox实现选择多条记录
  • Just SQL Part II – The Simple SELECT
  • 【随机文章】
  • SSH Client for windows
  • 转载:C/C++深层探索(八)
  • 速动画教程第十八集 SSH框架的构建(文档)
  • 用Java编写简单的UDP网络通信程序
  • 开发大型PHP项目的方法(一)
  • 用WinOnCD刻录原声CD
  • 深入了解接口技术
  • 毕业一年了,你的编程技术长了多少?
  • 官僚制度和程序设计
  • AutoCAD 2000 二级培训大纲
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.