Lua 同步调用 C 异步函数。

使用以下代码调用Lua的C函数:

if ( lua_pcallk(L, 0, LUA_MULTRET, 0, ctx, pcallk_continue) != 0 )
{}

Lua代码如下:

local coroutine = coroutine
co = coroutine.create( function (...)
c.call(...)
    -- [run here]
end )

c.call()是一个异步C函数(在函数结尾处调用lua_yieldk(),直到网络接收到数据并调用lua_resume())

return lua_yieldk(L, 0, 0, yield_continue);

它运行到 yield_continue 函数,但没有运行到 "[run here]" 的那行代码,为什么?

参考网址:http://www.lua.org/manual/5.2/manual.html#4.7

点赞
用户2328287
用户2328287

这是 dispatcher 的主要思路。

工作线程启动异步操作,并切换到 dispatcher 线程。 dispatcher 线程轮询异步操作,当它们完成时切换回工作线程。

-- 基本异步操作队列
local ASYNC_RECV = {}

-- 将操作放入队列并等待
local function recv()
  local co = coroutine.running()

  -- 在这里开始异步操作
  ASYNC_RECV[co] = true
  -- 在这里切换到 dispatcher
  return coroutine.yield()
end

coroutine.wrap(function()
  for i = 1, 10 do print(recv()) end
end)()

-- 主循环
-- 在这里轮询所有的异步操作并
-- 恢复相应的协程

while true do
  -- 没有异步操作了
  if not next(ASYNC_RECV) then break end

  for co in pairs(ASYNC_RECV) do
    ASYNC_RECV[co] = nil -- 标记操作已完成
    coroutine.resume(co, "some string") -- 将结果发送给协程
  end
end

这里展示了使用 libuv 作为 dispatcher 的示例:

local uv = require "lluv"

local function sleep(timeout)
  local co = coroutine.running()

  -- 在这里开始异步操作
  uv.timer():start(timeout, function(timer)
    timer:close() -- 只需要关闭无用的计时器即可。

    -- `dispatcher` (`libuv`) 调用此回调函数并
    -- 回调函数切换到协程。
    coroutine.resume(co)
  end)

  coroutine.yield()
end

coroutine.wrap(function()
  for i = 1, 10 do
    print("Tick")
    sleep(1000)
  end
end)()

uv.run()
2014-12-29 10:44:16