如何处理不包含coroutine.yield()的Lua库?
2012-11-11 21:59:4
收藏:0
阅读:151
评论:2
我想下载一个大文件,并同时处理其他事情。
然而,luasocket.http 从来不调用 coroutine.yield()。当文件下载时,其他所有东西都会冻结。
以下是一个说明性的示例,我尝试同时下载文件和打印一些数字:
local http = require'socket.http'
local downloadRoutine = coroutine.create(function ()
print 'Downloading large file'
-- Download an example file
local url = 'http://ipv4.download.thinkbroadband.com/5MB.zip'
local result, status = http.request(url)
print('FINISHED download ('..status..', '..#result..'bytes)')
end)
local printRoutine = coroutine.create(function ()
-- Print some numbers
for i=1,10 do
print(i)
coroutine.yield()
end
print 'FINISHED printing numbers'
end)
repeat
local printActive = coroutine.resume(printRoutine)
local downloadActive = coroutine.resume(downloadRoutine)
until not downloadActive and not printActive
print 'Both done!'
运行它会产生这个:
1
Downloading large file
FINISHED download (200, 5242880bytes)
2
3
4
5
6
7
8
9
10
FINISHED printing numbers
Both done!
如您所见, printRoutine 优先执行 resume。它打印数字 1 并 yield。然后重新启动 downloadRoutine,它会下载整个文件而不 yield。然后才打印其余数字。
我不想编写自己的套接字库!我能做什么?
编辑(同一天晚些时候):一些 MUSH 用户也注意到了,他们提供了有用的想法。
点赞
用户1442917
我不明白为什么你不能使用PiL建议或者Copas库(这与这里给出的答案几乎相同)。
Copas封装了socket接口(不是socket.http),但是你可以使用低级接口来获取你需要的东西,类似这样(未测试):
require("socket")
local conn = socket.tcp()
conn:connect("ipv4.download.thinkbroadband.com", 80)
conn:send("GET /5MB.zip HTTP/1.1\n\n")
local file, err = conn:receive()
print(err or file)
conn:close()
然后你可以使用copas的addthread来给你一个非阻塞的socket,使用step/loop函数在有接收到任何数据时执行receive操作。
使用copas较少工作量,而直接使用settimeout(0)则能给你更多控制。
2012-11-12 22:33:41
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
协程不是线程;协程是合作的,而非同时执行的。当一个协程从另一个协程中 yield 或返回时,它会被阻塞。在普通的 Lua 中,你不能有两个同时执行指针。
然而,你可以使用外部库实现这个效果。其中最流行的是Lua Lanes。