workflow icon indicating copy to clipboard operation
workflow copied to clipboard

workflow 能否用 poll 替换 epoll 实现 (嵌入式)

Open zhoujianyuhh opened this issue 3 years ago • 20 comments

将 workflow 移植到 qnx 平台,因 qnx 平台没有 epoll,打算改用 poll 替换 epoll,或者有更好的方案?正在阅读源码过程中,能否给予一些建议帮助?

zhoujianyuhh avatar Jul 22 '21 06:07 zhoujianyuhh

你好,我们先了解一下这个平台。这个是某种unix平台吗?poll的话应该可以改,毕竟现在kqueue和epoll都支持了。我一会看看。 通过那个宏来判断qnx平台呢?__linux__,__MACH__这种编译器定义的宏。

Barenboim avatar Jul 22 '21 06:07 Barenboim

QNX是遵从POSIX规范的类Unix硬实时操作系统。这是一个商业版的操作系统。 编译链也是需要licence的,通过__QNX__来判断平台。 如果没有该编译链的话,可以先在 linux 宏下将 epoll 改用 poll 实现功能。

zhoujianyuhh avatar Jul 22 '21 07:07 zhoujianyuhh

其它的都没有什么,但现在有个小问题,我们需要依赖linux的timer_fd或kqueue的timer。posix标准的话,我们得看看有什么可以代替。 另外,请问你们是做嵌入式开发的吗?很想了解一下workflow在嵌入式领域现在的用的怎么样。

Barenboim avatar Jul 22 '21 09:07 Barenboim

这是一份qnx开发手册,可以查询qnx支持那些API: http://www.qnx.com/developers/docs/7.1/index.html qnx平台有 timer_create()。 是嵌入式开发。 目前 http 相关的功能已经在使用状态,redis、kafka 打算尝试使用。

zhoujianyuhh avatar Jul 22 '21 09:07 zhoujianyuhh

我看看这个文档。也麻烦您向嵌入式圈子扩散一下我们这个框架。 嵌入式编译时,也可以通过: $ make REDIS=n MYSQL=n UPSTREAM=n 的方式,关闭编译一个或多个不必要的模块。最后strip一下,库文件最小可以降到400KB。

Barenboim avatar Jul 22 '21 10:07 Barenboim

好的,workflow 工作流的设计思想十分赞,正在借鉴使用。

zhoujianyuhh avatar Jul 22 '21 10:07 zhoujianyuhh

目前有什么进展不?

zhoujianyuhh avatar Jul 27 '21 02:07 zhoujianyuhh

还没有……主要还是timer的问题。我想做个posix版,但现在严重依赖timerfd。posix下timerfd不知道怎么代替。 如果没有timer_fd,需要每1ms或每10ms让poll调用超时,检查过期的fd或定时器。以前用过这个方法,可以是可以,就是非常的难看。

Barenboim avatar Jul 27 '21 03:07 Barenboim

好的,我这边也在看看,我之前已经尝试修改过代码,遇到的问题和你一样,就是 poll 怎么监测 fd 和 timefd的问题有点棘手。

zhoujianyuhh avatar Jul 27 '21 03:07 zhoujianyuhh

问一下,现在支持 https 协议吗? README中未看到标注。

zhoujianyuhh avatar Jul 27 '21 03:07 zhoujianyuhh

支持的呀。我们很多例子都是https的URL。server的话,有个启动接口可以传证书文件路径的。传了就是https server。

Barenboim avatar Jul 27 '21 03:07 Barenboim

Hi,请问一下,使用HttpServer,如何设置支持跨域访问?

zhoujianyuhh avatar Sep 10 '21 01:09 zhoujianyuhh

不太清楚什么是跨域访问……我们的http_server,基本就是把所以信息都给到用户,用户在这个基础上再做二次封装。同一个server支持多个Host肯定是没问题的。 如果是https serer,不同的Host可以配置不同的证书,这个是TLS SNI功能,我们也支持。需要派生一下WFHttpServer类。

Barenboim avatar Sep 10 '21 04:09 Barenboim

我发现我们的模式和其他one loop per thread的框架不一样。我们的模式下一个线程在epoll_wait,另一个线程向epoll里添加,删除或修改fd是常规操作。epoll和kqueue都支持这个特征,但poll就做不到了。这也是为什么我们不好用poll来实现目前的poller接口。 one loop per thread的框架,对poller操作是单线程的,添加删除fd都在回调函数里,不会与wait同时进行。难道one loop per thread这个搞不会慢吗?懂得麻烦科普一下。

Barenboim avatar Nov 14 '21 06:11 Barenboim

muduo也是使用的 one loop per thread,muduo以高性能著称,应该在高并发的性能上不会有太大的问题的。

zhoujianyuhh avatar Nov 23 '21 06:11 zhoujianyuhh

目前posix(poll)版本已经有一定进展,可以不用timer_fd,定时精度也不会有太大影响,可以到毫秒级。但性能上会比epoll差一些。

Barenboim avatar Nov 23 '21 06:11 Barenboim

好的,十分感谢。

zhoujianyuhh avatar Nov 23 '21 07:11 zhoujianyuhh

muduo也是使用的 one loop per thread,muduo以高性能著称,应该在高并发的性能上不会有太大的问题的。

muduo通过eventfd打断epoll_wait来添加fd。在一些场景下肯定会影响性能。

Barenboim avatar Nov 23 '21 07:11 Barenboim

小建议: 如果只是定时器,可以不依赖timer_fd,可以在每个poller里面管理一个自定义时间事件的优先队列,于是: 1、每次epoll_wait的时候,如果有时间事件,计算距离当前时间最近的时间事件的时长,作为epoll_wait的时间参数; 2、当epoll_wait返回的时候,如果有时间事件到期了,就处理一下时间事件。 redis就是采用的这种方法。

chaos318 avatar Mar 03 '23 06:03 chaos318

小建议: 如果只是定时器,可以不依赖timer_fd,可以在每个poller里面管理一个自定义时间事件的优先队列,于是: 1、每次epoll_wait的时候,如果有时间事件,计算距离当前时间最近的时间事件的时长,作为epoll_wait的时间参数; 2、当epoll_wait返回的时候,如果有时间事件到期了,就处理一下时间事件。 redis就是采用的这种方法。

我之前就是这么做的,但没有实现完代码给删了。当时肯定是对代码实现不满意。因为poll和epoll/kqueue的用法区别上实在太大,不能多线程操作,我们的poller极度依赖于线程安全,必须可以多线程并发操作。如果我还只保留一个poller.c文件,需要加入很多ifdef,这个不能接受。只能独立出来一个新的poller实现,这样又有很多重复代码。大家有兴趣可以用poll来实现现在poller的语义试试。

Barenboim avatar Mar 03 '23 07:03 Barenboim