lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


  I decided to play around with preemption of Lua coroutines.  My initial
thought was to call debug.sethook() with a cycle count and when that hook
was triggered, call coroutine.yield() in the debug hook.  Only that didn't
quite work---the coroutine was instantly killed.  I have some code
(presented below) that does what I want (round robin among several
coroutines) but I have to include an explicit coroutine.yield() in the
coroutines being round-robinned.  If I don't, when the hook is called, the
coroutine is killed (which, frankly, makes what I was attempting much
easier), which is puzzling to me.

  What, exactly, is going on?

  -spc (Extremely puzzled)

--  >8 CODE HERE 8< ------------------

local function spinner()
  local x = 0
  while true do

    -- --------------------------------------------------------------------
    -- if the fllowing line is uncommented, then this runs just fine (well,
    -- as fine as sucking up 100% of the CPU can be) and the multiple
    -- coroutines work round-robin.  But if you leave this commented out,
    -- then when the debug hook is fired, the coroutine.yield() call there
    -- kills the running coroutine.
    --
    -- Am I missing something?
    -- --------------------------------------------------------------------
  
    -- if x % 100 == 0 then coroutine.yield() end  
    x = x + 1
  end
end  
     
local function hook()
  -- ----------------------------------------------------------------------
  -- If this is commented out, then the coroutines will never be killed when
  -- the coroutine's "timeslice" is up.
  -- ----------------------------------------------------------------------
  coroutine.yield()
end
   
code =
{
  coroutine.create(spinner),
  coroutine.create(spinner) 
}
 
while #code > 0 do
  local co = table.remove(code,1)

  debug.sethook(co,hook,"",1000) -- change to lengthen/shorten timeslice
  coroutine.resume(co)
  -- print(">>> switch") -- uncomment to show coroutine switching
  if coroutine.status(co) ~= 'dead' then
    table.insert(code,co)
  else
    print("co",co,"too busy, killed")
  end
end