免费注册 查看新帖 |

Chinaunix

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

[C] 从多个缓冲区取数据的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-07 18:31 |只看该作者 |倒序浏览
小弟弟我要实现的功能如下:
    首先每个端口建一个循环缓冲池,将多个网口收到的数据写到对应的缓冲池里,应用程序不断的判断每个端口的缓冲区是否有数据,有数据则将数据取出。
我用一个线程,轮询每个端口,判断有数据,则取出。过程大致如下:

  1. for(;;)
  2.     {
  3.         for(port = 0; port < MAX_PORT_NUM; port++)
  4.         {
  5.             if(端口缓冲区有数据)
  6.             {
  7.                 取出数据;
  8.             }
  9.         }
  10.         sleep(0);
  11.     }
复制代码
sleep(0)可以使线程让出时间片,所有端口都没数据时,不占CPU。但现在有个问题:当一个端口收包时,CPU占用95%左右,而多个口收包的时候,CPU反而更低,全部收包CPU占70%左右。我想是不是因为使用sleep(0)的问题。如果sleep()时间改大,又担心会丢数据。有什么好的方法能够解决这个问题吗?

论坛徽章:
0
2 [报告]
发表于 2012-12-07 19:15 |只看该作者
不要采用这种循环检查,有数据时用信号通知或者条件变量。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
3 [报告]
发表于 2012-12-09 21:08 |只看该作者
epoll, 或者用用lua的协程配合epoll避免cpu繁忙.

论坛徽章:
0
4 [报告]
发表于 2012-12-10 09:51 |只看该作者
回复 3# linux_c_py_php


    谢谢。我将sleep(0)改成了usleep(0),这样就只有在有数据的时候,才会占用CPU。不清楚sleep(0)和usleep(0)有什么区别。epoll还没用过,等我写个epoll的版本,对比下。

论坛徽章:
0
5 [报告]
发表于 2012-12-10 17:23 |只看该作者
linux_c_py_php 发表于 2012-12-09 21:08
epoll, 或者用用lua的协程配合epoll避免cpu繁忙.


epoll?还整出lua来了?至于吗...

一台机器没有几块网卡,LZ用select搞定吧

sleep(0)不能保证让出CPU,即便能够让出,也不应该在分时系统上应用这种忙等算法。

论坛徽章:
0
6 [报告]
发表于 2012-12-11 17:10 |只看该作者
回复 5# JohnBull


    谢谢版主。共有8个端口收数据,在内核中,对应缓冲区是自定义物理内存连续的缓冲区,我加入了过滤,只有指定报文数据才会存入缓冲池。select函数怎么检测自定义缓冲区有没有数据呢?
    操作系统为嵌入式linux,sleep(0)不能保证让出CPU,usleep(0)的确让出CPU了(没搞清楚这俩有啥区别),在无数据的时候CPU为0。

论坛徽章:
0
7 [报告]
发表于 2012-12-14 18:50 |只看该作者
haichang417 发表于 2012-12-11 17:10
回复 5# JohnBull


不是以描述符形式操作的?那可不能用select,我以为你是操作socket呢

如果这个机器只干这一件事情,或者负载不重的话干脆就忙等吧,不要用sleep(0),用sched_yield()

论坛徽章:
1
技术图书徽章
日期:2014-03-06 15:32:30
8 [报告]
发表于 2012-12-14 22:59 |只看该作者
可以试试加个有数据的标识
    for(;
        {
            int fond = 0;
            for(port = 0; port < MAX_PORT_NUM; port++)
            {
                if(端口缓冲区有数据)
                {
                    fond = 1;
                    取出数据;
                }
            }
            if ( fond == 0 ) usleep(1);
        }
不过这个模式也不太好。
1、你的线程就只做这一件事么?
2、会不会有增加或者删除一个端口的需求?
     要不要考虑封装成epoll模式或者select模式的方式作为基础框架来用?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP