client 用 poll 方式收发消息,会不会比同步阻塞方式功耗更大 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
paparika
V2EX    Linux

client 用 poll 方式收发消息,会不会比同步阻塞方式功耗更大

  •  
  •   paparika 2018-08-09 18:15:15 +08:00 2928 次点击
    这是一个创建于 2642 天前的主题,其中的信息可能已经有所发展或是发生改变。

    client 用 poll 机制发消息,如果 poll 的轮询间隔太久话,消息最坏要等一个间隔时间才发送,但是轮询间隔设在百毫秒级,有点担心是不是浪费 cpu 资源。cpu 占用跟同步阻塞方式比呢?

    15 条回复    2018-08-10 10:10:54 +08:00
    MeteorCat
        1
    MeteorCat  
       2018-08-09 18:22:50 +08:00 via Android
    poll 轮询是在有 POLLIN 之后触发 pollfds 轮询的吧,POLLIN 之后一直没有拿他处理
    MeteorCat
        2
    MeteorCat  
       2018-08-09 18:23:43 +08:00 via Android
    @MeteorCat 除非接收到 POLLIN 事件一直不做处理
    paparika
        3
    paparika  
    OP
       2018-08-09 18:27:25 +08:00
    @MeteorCat 具体细节记不清了,回头再查下。先问下”如果 poll 的轮询间隔太久话,消息最坏要等一个间隔时间才发送“,这个结论正确吗,有办法消息能几乎立即发送吗
    MeteorCat
        4
    MeteorCat  
       2018-08-09 18:31:31 +08:00 via Android
    @paparika 这个分情况来看,如果你 client 只连接一个服务器,那轮询也只是对一个轮询,到达肯定是立即到达的;如果你 client 是和多个服务器连接的,poll 循环间隔会随着你连接服务端数量增加[前提是不使用线程进程,全部在主线程跑]
    paparika
        5
    paparika  
    OP
       2018-08-09 18:39:52 +08:00
    @MeteorCat 刚才我描述的可能有问题,现在是这样,我在一个线程里循环 poll,间隔是 10s,然后另外一个线程发起连接服务器,发现要基本过了 10s 才真正有发起连接的动作
    MeteorCat
        6
    MeteorCat  
       2018-08-09 18:44:30 +08:00 via Android
    @paparika 必然的,你 poll 的 timeout 设定为 10s ?他会阻塞整个系统 10s 的,另外线程也会影响
    paparika
        7
    paparika  
    OP
       2018-08-09 18:44:36 +08:00
    基本上就是要等过了一个间隔时间后,才真正有连接动作。这里想问,这个是不是正常的,另外就是除了调小时间间隔,有其他办法吗
    MeteorCat
        8
    MeteorCat  
       2018-08-09 18:46:45 +08:00 via Android
    @paparika 算了你还是上代码吧,免得其他人猜半天
    paparika
        9
    paparika  
    OP
       2018-08-09 18:48:42 +08:00
    @MeteorCat 感觉设为百毫秒级别的话,频繁唤醒 cpu,应该是比同步阻塞方式功耗多不少吧
    paparika
        10
    paparika  
    OP
       2018-08-09 18:51:49 +08:00
    @MeteorCat 代码是用的一个库 mongoose,我先上下看个大概吧

    在一个独立线程里 poll
    void* Foobar::init_thread(void *arg){

    pthread_detach(pthread_self());

    while(loop){
    mg_mgr_poll(mgr, 10000);
    }

    return NULL;
    }

    在其它线程发起连接
    mg_connect_ws(&mgr, ev_handler, url,  WS_PROTOCOL, HEADER);
    MeteorCat
        11
    MeteorCat  
       2018-08-09 18:59:30 +08:00 via Android
    @paparika 你 timeout 设 10000 ?
    MeteorCat
        12
    MeteorCat  
       2018-08-09 19:03:36 +08:00 via Android
    @paparika https://linux.die.net/man/2/poll 如果我记得每次,poll 最后参数是设定内核事件检查的间隔
    paparika
        13
    paparika  
    OP
       2018-08-10 09:31:35 +08:00
    @MeteorCat 调试而已,设多少无所谓的。这个是库自己的 poll,不是标准函数。poll 机制不是来事件就退出阻塞态吗,连接应该也算事件,为啥会第二次进入 poll 才响应
    wwqgtxx
        14
    wwqgtxx  
       2018-08-10 09:53:54 +08:00
    “消息最坏要等一个间隔时间才发送”这个问题不难解决吧,linux 的 poll 是支持任意文件描述符的,你随便开一个空的文件描述符(比如 cpython 的做法,开一个 socketpair, https://github.com/python/cpython/blob/3.7/Lib/socket.py#L499 ),然后在你需要唤醒的时候往这个文件描述符对应的文件 write 一下不就可以退出 poll 的阻塞了,没必要“轮询间隔设在百毫秒级”吧
    paparika
        15
    paparika  
    OP
       2018-08-10 10:10:54 +08:00
    @wwqgtxx 多谢这个思路,不过我这个是现成的库,没具体看源码,可能需要改造下。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     819 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 21:52 PVG 05:52 LAX 13:52 JFK 16:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86