简体   繁体   English

lua同步调用C异步函数

[英]lua synchronous call C asynchronous function

c call lua with the following code c用以下代码调用lua

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

the lua code is lua代码是

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

c.call() is an asynchronous c function(it call lua_yieldk() at the end of the function, util the network recv the data and call lua_resume() ) c.call()是一个异步c函数(它在函数末尾调用lua_yieldk(),利用网络接收数据并调用lua_resume())

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

it run to yield_continue function, but not run to the line of "[run here]" , why? 它运行到yield_continue函数,但没有运行到"[run here]" ,为什么?

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

This is main idea with dispatcher. 这是调度员的主要思想。

Worker thread start async operation and switch to dispatcher thread. 工作线程启动异步操作并切换到调度程序线程。 Dispatcher thread polls async operations and when they done switch to worker thread. 分派器线程轮询异步操作,并在完成操作时切换到辅助线程。

-- basic async operation queue
local ASYNC_RECV = {}

-- Put operation to queue and wait
local function recv()
  local co = coroutine.running()

  -- here we start async operation
  ASYNC_RECV[co] = true
  -- here we switch to dispatcher
  return coroutine.yield()
end

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


-- main Loop
-- here we poll all async operation and 
-- resume according coroutines

while true do
  -- we have no async operation
  if not next(ASYNC_RECV) then break end

  for co in pairs(ASYNC_RECV) do
    ASYNC_RECV[co] = nil -- mark operation is done
    coroutine.resume(co, "some string") -- send result to coroutine
  end
end

And here work example with libuv as dispatcher 这是使用libuv作为调度程序的工作示例

local uv = require "lluv"

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

  -- here we start async operation
  uv.timer():start(timeout, function(timer)
    timer:close() -- just close unused timer.

    -- dispatcher(libuv) call this callback and
    -- callback switch to coroutine
    coroutine.resume(co)
  end)

  coroutine.yield()
end

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

uv.run()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM