免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
61 [报告]
发表于 2013-02-24 23:17 |只看该作者
linux_c_py_php 发表于 2013-02-24 23:08
我的意思是当整个lua脚本跑完了, server却不知道它跑完了, 这个连接挂住了, 除非有外力推动它说: 当前的请求已经跑完lua了, 你可以继续处理下一个了.


lua是server同步调用的,它返回时server不知道它跑没跑完?你不能检查下coroutine的状态是dead还是paused?

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
62 [报告]
发表于 2013-02-24 23:20 |只看该作者
回复 59# linux_c_py_php


    所以我实在不知道你的问题是什么= =

对插件来说,会有update的轮询,询问当前工作做完没,但coroutine不会。

coroutine resume就是在干活,返回了就是干完了(至少是部分干完了),所以就不存在轮询问题了= =

我真不知道你是哪儿有问题啊= =我建议你先不管服务器,先理解一下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
63 [报告]
发表于 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
64 [报告]
发表于 2013-02-24 23:23 |只看该作者
windoze 发表于 2013-02-24 23:17
lua是server同步调用的,它返回时server不知道它跑没跑完?你不能检查下coroutine的状态是dead还是paus ...


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

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
65 [报告]
发表于 2013-02-24 23:24 来自手机 |只看该作者
你难道不觉得在你这个程序里需要自己实现connect/read/write么?
用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
66 [报告]
发表于 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

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
67 [报告]
发表于 2013-02-24 23:28 |只看该作者
回复 63# linux_c_py_php


    太好了,终于说到点子上了,我知道你的死结在哪儿了。

你的意思是不是,假设我有个API叫connect,然后事件来了以后connect这个API负责resume?

你完全理解错了~~~

不是,绝对不是这样。

当connect被yield(假设是C写的),是resume之后才会执行k函数,而不是相反,所以必须有个人resume以后,那个k才会被执行,k根本没机会resumeLua脚本的。

而谁有这个能力resume?只有框架!

不是每个API去resume,resume coroutine的地方只有一个!就是框架。你在哪儿resume那个脚本的,就是在哪儿【当然不是原地了】resume每个API被yield掉的coroutine。假设有1000个coroutine被yield了,你也只在一个地方resume。

这个地方在哪儿呢?在epoll函数返回后的那个地方!因为只有那个地方你才知道哪个coroutine被执行完了。然后resume,然后执行k函数,k函数负责把coroutine从注册信息里面去掉(这个都可以是通用函数的),然后返回到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
68 [报告]
发表于 2013-02-24 23:32 |只看该作者
我草,

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

你说的是epoll_wait之前, 遍历所有coroutine, 哪些yield了就给它resume了。, 哪些dead了就更改其状态让它继续处理下一个请求?

论坛徽章:
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
69 [报告]
发表于 2013-02-24 23:34 |只看该作者
本帖最后由 linux_c_py_php 于 2013-02-24 23:37 编辑
  1. connect_100times.lua:

  2. for i=1, 100 do
  3.      succeed, connUserData = server:connect('localhost', 80) -- 底层是epoll下的非阻塞connect
  4.      ...
  5.      ...
  6.      server:close(connUserData)
  7. done
复制代码
擦, 我这段代码要求在connect的fd的event callback里创建一个userdata叫connUserData, 里面包含连接成功的socket等相关信息的结构体, 如果是框架级别集中yield, 这个值怎么可能给它resume到connect api的实现里去并返回给lua用户啊, 难道直接用C赋值socket等信息到server里, 然后在connect的Yield点之后再根据server里的信息创建userdata啊, 或者又用独立的table做记录啊,太绕了吧? 不合理啊, 我认为yield是定制的啊, 不是框架级别的啊.

我擦, 我又理解错了吗

论坛徽章:
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
70 [报告]
发表于 2013-02-24 23:39 |只看该作者
我疯了, 元宵佳节倍思亲, 赶紧打破迷津, 解决本帖吧.. {:3_198:}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP