lua:写了个基于协程的task调度库

Posted cutepig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua:写了个基于协程的task调度库相关的知识,希望对你有一定的参考价值。

写了一个(不完整的)基于协程的task调度库

 

sample code如下

my_spawn(
  function ()
    print(f: 1)
    
    local t1 = my_spawn(
      function ()
        print(f: 3)
        task_yield_to_be_schedule()
        print(f: 4)
      end
    )
    
    --task_yield_to_be_schedule()
    my_wait_task(t1)
    print(f: 2)
  end
)

local num_run = 0
while my_run_once() do
  dbgprint(>>exec , num_run)
  num_run = num_run + 1
end

 

features

  • 支持spwan
  • 支持在task里面spawn
  • 支持task里面yield
  • 支持task里面等待其他task

todo

  • 支持在task里面sleep
  • 支持在task里面设置和等待event

 

 

完整源代码如下

require(mobdebug).coro() 
local inspect = require(inspect)

local debug_on = true

local function dbgprint(...)
  if debug_on then
    print(...)
  end
end

if false then
  function f()
    print(in f)
    coroutine.yield(100)
    print(in f2)
    
  end

  local task1 = coroutine.create(f)
  print(coroutine.status(task1))
  local ret, r2, r3 = coroutine.resume(task1)
  print(ret)
  print(coroutine.status(task1))
  print(coroutine.resume(task1))
  print(coroutine.resume(task1))
  print(coroutine.status(task1))
  
  return
end



-- scheduler
-- lowlevel support: spawn, wait, events and timeout

-- to be run tasks
local tasks_to_be_scheduled = 

-- to be timeout tasks
local tasks_to_be_timeout = 

-- to be set event tasks
local tasks_to_be_event = 

-- to be waited tasks, this is a map where key is task handle, value is the tasks waiting this task
local tasks_to_be_wait = 

-- task yield flags
local yield_flag_to_be_schedule = 1
local yield_flag_timeout = 2
local yield_flag_event = 3
local yield_flag_wait_task = 3

function my_spawn(f)
  local t = coroutine.create(f)
  table.insert(tasks_to_be_scheduled, t)
  return t
end

function my_run_once()
  
  -- loop to be scueduled tasks
  if #tasks_to_be_scheduled > 0 then
    
    -- fetch a task
    local t = table.remove(tasks_to_be_scheduled, 1)
    assert(coroutine.status(t)=="suspended")
    
    -- exec
    local ret, data1, data2 = coroutine.resume(t)
    dbgprint (>>resume coroutine returns , ret, inspect(data1), data2)
    assert(ret)
    
    -- handle following
    if coroutine.status(t) ~= dead then
      assert(data1 and data1.yield_flag)
      local dispatch=
      dispatch[yield_flag_to_be_schedule] = function ()
        table.insert(tasks_to_be_scheduled, t)
      end
      
      dispatch[yield_flag_wait_task] = function ()
      end
      
      local disp = dispatch[data1.yield_flag]
      if disp then
        disp()
      else
        assert(0)
      end
    else
      -- loop to see who are waiting this task?
      local tasks_to_be_schedule = tasks_to_be_wait[t]
      if tasks_to_be_schedule then
        dbgprint (>>trigger depent tasks , inspect(tasks_to_be_schedule))
        for i, task_to_be_schedule in ipairs(tasks_to_be_schedule) do
          table.insert(tasks_to_be_scheduled, task_to_be_schedule)
        end
        tasks_to_be_wait[t] = nil
      end
      
    end
    
    return true
  end
  
  return false
end

function task_yield_to_be_schedule()
  coroutine.yield (yield_flag=yield_flag_to_be_schedule)
end

function my_wait_task(t)
  -- when t done, need notify this_task
  local this_task = coroutine.running()
  if not tasks_to_be_wait[this_task] then
    tasks_to_be_wait[t] = this_task
  else
    table.insert(tasks_to_be_wait[t], this_task)
  end
  
  -- yield from current task
  coroutine.yield (yield_flag=yield_flag_wait_task, handle=t)
end

my_spawn(
  function ()
    print(f: 1)
    
    local t1 = my_spawn(
      function ()
        print(f: 3)
        task_yield_to_be_schedule()
        print(f: 4)
      end
    )
    
    --task_yield_to_be_schedule()
    my_wait_task(t1)
    print(f: 2)
  end
)

local num_run = 0
while my_run_once() do
  dbgprint(>>exec , num_run)
  num_run = num_run + 1
end

 

以上是关于lua:写了个基于协程的task调度库的主要内容,如果未能解决你的问题,请参考以下文章

Lua-Async 协程的高级用法

Lua中协程的使用

对协程的理解

Lua协程的应用

python之进程线程协程的调度原理

Kotlin 协程的四种启动模式