免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: linux_c_py_php
打印 上一主题 下一主题

[其他] 【(LUA相关)一个支持yield的server能避免掉轮询检查coroutine状态的命运吗?】 [复制链接]

论坛徽章:
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
31 [报告]
发表于 2013-02-24 22:52 |显示全部楼层
starwing83 发表于 2013-02-24 22:44
回复 39# linux_c_py_php


这一点我同意。

论坛徽章:
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
32 [报告]
发表于 2013-02-24 22:55 |显示全部楼层
本帖最后由 linux_c_py_php 于 2013-02-24 22:59 编辑
starwing83 发表于 2013-02-24 22:46
回复 42# linux_c_py_php


这个卡着是允许的, 是正常的, 对于那些该yield出去并且去epoll里跑异步的如果还卡着跑, 那就不对了.

我说的都是正常情况, 比如给lua提供个connect接口, 实际底层是注册给epoll后立马就yield了, 等connect事件完成会resume去跑剩下的lua逻辑, 当然剩下的lua逻辑又会有类似的接口, 如此resume->yield不停往复, 直到lua代码全部执行完. 但天知道你调用100次connect到底哪时候能把整个lua脚本跑完, 我的server是不知道的, 我只有coroutine的lua_State可以看status, 与此同时也许这个lua脚本里的第N次connect正在epoll里异步的执行着:

connect_100times.lua:

for i=1, 100 do
     succeed, connUserData = server:connect('localhost', 80) -- 底层是epoll下的非阻塞connect
     ...
     ...
     server:close(connUserData)
done

我的脚本就要这样跑, 第99次resume返回到非阻塞connect的event callback中时, 我并不打算在这里检查coroutine死了没有, 于是server对lua脚本执行结束毫不知情, 我就是要解决这个"毫不知情".

论坛徽章:
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
33 [报告]
发表于 2013-02-24 23:06 |显示全部楼层
本帖最后由 linux_c_py_php 于 2013-02-24 23:17 编辑
windoze 发表于 2013-02-24 22:56
回复 49# linux_c_py_php

coroutine当然不会“没完没了”,当你调用阻塞调用比如read/write,或者主动y ...
\

本来就是这样, 我没否认这个啊, 这个我肯定知道, 这些东西我已经掌握了...

但什么时候继续处理下一个请求?

如果是starwing87的coroutine脚本的思路, 那么其实就是server解析了request就放到一个队列里存着, 然后立马看一下当前coroutine是否yield在了wait上, 如果是就resume, 否则坐视不管(因为只可能是yield在move上了, 等下次lua被resume再次跑到wait肯定会检测到队列里的请求, 于是不会yield而是继续跑while内), 这一点我没理解错吧。

这个我理解, 相当于传统C开发里的线程池, 你的coroutine相当于一个业务线程永不退出.

我的做法相当于来一个连接创建一个线程, 干完一个短连接请求就挂掉线程.

论坛徽章:
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
34 [报告]
发表于 2013-02-24 23:08 |显示全部楼层
本帖最后由 linux_c_py_php 于 2013-02-24 23:10 编辑
starwing83 发表于 2013-02-24 23:05
回复 51# linux_c_py_php


是啊啊啊啊啊!!!!!!!!!!!!1

你们大爷的, 你们以为我低能?

这些lua和epoll交互我肯定懂, 草, 我当然知道100个connect是顺次发生的, 一次resume->yiled发生一次, 每次都会需要借助epoll做异步的连接事件.

我的意思是当整个lua脚本跑完了, server却不知道它跑完了, 这个连接挂住了, 除非有外力推动它说: 当前的请求已经跑完lua了, 你可以继续处理下一个了.


我的疑惑你们懂吗,我擦, 敢不敢不要用看新手的角度看问题, 这些JB玩意我肯定都懂.

论坛徽章:
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
35 [报告]
发表于 2013-02-24 23:13 |显示全部楼层
nginx/lighttpd的插件架构, 敢不敢拿这些东西来理解我的意思啊.

它们都支持你的插件可以yield出来, 它们是通过不断的轮询插件, 给插件cpu使用, 直到插件说它已经处理完了.

这和这里轮询coroutine是否完成有个JB区别啊, 有没有啊.

论坛徽章:
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
36 [报告]
发表于 2013-02-24 23:15 |显示全部楼层
我不用lua一样实现可以yield的c server, 之前都开过一个帖子, 用lua对我来说觉得有用处的就是可以让小白写阻塞一路到底的代码, 但实际上是高效的异步处理.

如果让小白去给nginx开发个模块, 它能行吗, 所以不就有了nginx-lua吗, 但尼玛nginx-lua也是nginx module, 是要被nginx的插件机制不断轮询: "你搞定了没? 没搞定过会在来问题你", 这和coroutine自身的yield和resume没有半毛钱关系。

论坛徽章:
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
37 [报告]
发表于 2013-02-24 23:22 |显示全部楼层
本帖最后由 linux_c_py_php 于 2013-02-24 23:23 编辑
starwing83 发表于 2013-02-24 23:17
回复 56# linux_c_py_php


就是嘛, 终于到点子上了.

resume是谁调用的? 除了第一次是框架调用的, 后面都是类似于connect这种lua api, 它是在epoll触发connect完成事件后调用的resume, 框架是不知道的...

如果把这个检查LUA_OK/LUA_YIELD的责任交给每个lua api的底层实现上, 这是多么蛋疼的事情.

但如果我通过epoll超时轮询每个正在工作的coroutine是否dead, 或者在调用lua脚本前, 使用一个C的包装来pcallk调用lua脚本, 那么一旦我的C包装里pcall返回了, 那么就知道lua脚本执行完了, 此时执行权在我框架的手里, 我就立马可以知道lua执行完了进行一些处理以便框架开始处理下一个请求.

我就是这么一个问题啊, 怎么说了6页都木有说利索... 肯定是你的死循环版本和我的coroutine死亡版本造成了理解偏差.

论坛徽章:
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
38 [报告]
发表于 2013-02-24 23:23 |显示全部楼层
windoze 发表于 2013-02-24 23:17
lua是server同步调用的,它返回时server不知道它跑没跑完?你不能检查下coroutine的状态是dead还是paus ...


resume只有第一次是server调用的, 后续的resume不是server调用的, 这一点很关键吧.

论坛徽章:
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
39 [报告]
发表于 2013-02-24 23:26 |显示全部楼层
windoze 发表于 2013-02-24 23:24
你难道不觉得在你这个程序里需要自己实现connect/read/write么?
用lua自带的你搞个毛啊


不是lua自带啊, 是我为lua实现connect/read/write这些lua傻瓜api, 用户用这些来编写proxy脚本会很傻瓜并且很高效(因为借助epoll在异步的做), 这些api的底层实现都会用到resume和yield, 所以这个resume返回值对于我server框架来说根本不知情啊, 有木有啊, 你们说有木有!!!!!!我很激动了!!1

论坛徽章:
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
40 [报告]
发表于 2013-02-24 23:32 |显示全部楼层
我草,

我认为是connect注册在epoll上的那个fd的callback里来做针对这个coroutine的resume.

你说的是epoll_wait之前, 遍历所有coroutine, 哪些yield了就给它resume了。, 哪些dead了就更改其状态让它继续处理下一个请求?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP