免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 8780 | 回复: 8
打印 上一主题 下一主题

线程里select使cpu占用率%100? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-12-08 11:42 |只看该作者 |倒序浏览
我做的是apache server 的module.每个用户连接对应一个长连接线程(也就是apache module的一次请求处理),每个线程用select监听两个socket.
程序模型如下;


  1. while(1)
  2.     {
  3.         FD_ZERO(&rset);
  4.         FD_SET(sockfd,&rset);//sockfd,fifo都设置成了非阻塞的。
  5.         FD_SET(fifo,&rset);

  6.         time.tv_sec = 10;
  7.         time.tv_usec = 0;
  8.         int sel = select(maxfd + 1,&rset,NULL,NULL,&time);//最后一个参数设置成NULL也不行。
  9.         if(sel <= 0)
  10.               continue;                                                      //用户只有200左右,应该不会超过select的文件描述符限制吧?
  11.        if(FD_ISSET(fifo, &rset))
  12.        {
  13.                .......//对应处理。
  14.         }
  15.         if(FD_ISSET(sockfd, &rset))
  16.         {
  17.            对应处理
  18.       }
  19. }   
复制代码


但改成如下的模型cpu利用率就降到了%1.

  1. while(1)
  2.     {
  3.         nanosleep(&time, NULL);//就是每0.2秒看一下两个非阻塞文件描述符是不是有数据,有就处理。
  4.        if(1)
  5.        {
  6.                .......//对应处理。
  7.         }
  8.         if(1)
  9.         {
  10.            对应处理
  11.       }
  12. }   
复制代码


在200个左右的线程里每个都用用select为何会使cpu利用率那么高,不明白为什么,请各位大侠多多指教!

论坛徽章:
0
2 [报告]
发表于 2006-12-08 12:17 |只看该作者
不知道是不是因为select的原因, 两百个10S
你可以把usec改为1000. 再看看.如果后来不是100%,那么就是select的原因了.

select是个界面,最后还要使用更底层具体设备的select.

按说也不应该这么多时间, 你测试一下程序的那几个时间.看看是不是系统时间非常多.

论坛徽章:
0
3 [报告]
发表于 2006-12-08 12:43 |只看该作者
多谢斑竹啊,我去试试看。确实用select的时候cpu的sy占用率非常高,所以我对select在线程里用很怀疑。

论坛徽章:
0
4 [报告]
发表于 2008-10-15 15:34 |只看该作者
不是说在线程里使用select的问题
在线程中使用select, 应该把时间那个选项设置为NULL!

论坛徽章:
0
5 [报告]
发表于 2008-10-15 17:03 |只看该作者
不要每个线程监听两个,不如改成主线程监听所有

论坛徽章:
0
6 [报告]
发表于 2008-10-15 21:08 |只看该作者
首先问下,你多个线程select的fd_set是不是同一个句柄集合?如果是这里可能有问题。
另外如果你的module 是作为客户端在用(我猜的,因为我这样用过),那么建议你为每个apache子进程(假设你用的prefork)维持一个到后端服务的长连接,这样会更好,不用担心到后端连接过多,它的多少依赖于apache子进程的增减,而子进程的多少是apache自动根据繁忙程度还有你的配置自动调节的,最多也不会有多少个,不建议用池是因为在apache请求繁忙的时候不会在这里出现瓶颈。

在module里操作句柄等系统资源要谨慎,一定要熟悉你apache所用的模式,prefork,worker or其它。

[ 本帖最后由 zhoubug 于 2008-10-15 23:11 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-10-15 21:20 |只看该作者
明显是fd没有处理好嘛,事件依然存在,导致死循环,socket异常应该可读可以处理,应该出在fifo身上,

建议将fifo放到excepfds中,看看是否已经异常。

论坛徽章:
0
8 [报告]
发表于 2010-10-30 10:32 |只看该作者
我发现是因为select加了超时时间后是非阻塞的,由此造成while不停循环,抢占了CPU

论坛徽章:
0
9 [报告]
发表于 2010-10-30 10:40 |只看该作者

  1. if(sel <= 0)
  2.                continue;   
复制代码
修改为

  1. if(sel <= 0) {
  2.     if (sel == -1) {
  3.         perror("select");
  4.     }
  5.                continue;   
  6. }
复制代码
另外确保数据读到EAGAIN为止。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP