lua-users home
lua-l archive

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


David Given wrote:
I have a project for which I'm going to want a large number of coroutines, all communicating via a scheduler. Unfortunately, while I'm pretty much up to speed with the rest of Lua, this isn't an area I've had much experience with.

When are these coroutines created ? all at once, or in response to some event ?

I remember reading on the list that using a scheduler in this way is not compatible with using coroutines to invert control flow, for example when using a producer/consumer system. This seems to be because the scheduler would have to resume a particular thread with coroutine.resume(), which means that when that thread yields, expecting to go back to its caller, it'll instead end up at the scheduler.

Yes, but the scheduler then resumes the "next" coroutine to proceed.

Are there any nifty ways round this?

The following pseudocode is a simplified version of what i'm using for a http proxy server.
(all the coroutine construction/scheduling is wrapped in the real thing)

-- note : threads is a collection of coroutines to be executed
active_thrd = nil

function startup()
  local thrd = coroutine.create(function() print("func1",active_thrd) end)
  -- schedule for immediate action (push onto threads collection)
  threads.push(thrd,0)

  thrd = coroutine.create(function() print("func2",active_thrd) end)
  threads.push(thrd,0)
  print("yielding")
  threads.push(active_thrd,0) -- re queue myself (vital !)
  coroutine.yield()
  print("i'm back")
  -- do more stuff
return true -- done with this thread


-- schedule the warmup
threads.push(coroutine.create(startup),0)

-- main scheduler
while (true)
   local thrd, args = threads.pop()
   if not thrd then break end
   active_thrd = thrd
   local status, ret, err = coroutine.resume(thrd, unpack(args))
   if not status then -- lua error or assert
      break
   end
end


note that this is co-operative multitasking- a thread will run until it yields.

(i'm converting to lua 5.1 - coroutine.running() removes the need to pass around the current thread)

In addition, is there any fundamental difference between coroutine.resume() and coroutine.yield(), apart from the fact that yield knows which coroutine to switch to automatically?
coroutine.yield() returns control to the caller, which may or may not be a coroutine.

Can I use resume() to keep switching between two
different coroutines without eating huge quantities of stack space?

I have run the proxy server for long periods without memory leakage or stack growth.

Adrian