54 posts
Posted 07 February 2014 - 09:12 PM
Q:) I was wondering if someone could clarify some points to me about coroutines and a management system for them. I've looked in to the parallel api to see how 'runUntilLimt' works and thats pretty clear to me but I was wondering if there's a more dynamic approach to running tasks or coroutines.
I've also looked into goroutine although some of that is a little above my head..
How can I manage a system where one coroutine or task can spawn new subroutines?
And further, would it be pointless to have a system where routines run and monitor themselves until they're finished and push themself off of the running coroutine stack / listOfActiveRoutines??
Let me know if im being too ambiguous or unclear.. Thanks in advance for any help
758 posts
Location
Budapest, Hungary
Posted 08 February 2014 - 03:37 AM
How can I manage a system where one coroutine or task can spawn new subroutines?
Managing coroutines is all about keeping them alive and not resuming them after they die. If you have a list of them, you can just provide a function in the global environment that adds coroutines to that list:
local crList = {}
function coroutine.start(func, ...) -- call this whatever you want
if type(func) ~= "function" then return false end
local cr = coroutine.create(func)
coroutine.resume(cr, ...) -- comment this if your coroutines yield at the end of their endless loops
crList[cr] = true -- yay, you can even store useful information here about the coroutine
end
coroutine.start(loadfile("rom/programs/shell"))
while true do
local eventData = {coroutine.yield()}
for key in pairs(crList) do
coroutine.resume(key, unpack(eventData))
end
if coroutine.status(key) == "dead" then crList[key] = nil end
end
As for the second question; coroutines can't check themselves if they are dead, because if a coroutine is checking itself, that means it is very much alive. You could of course put a wrapper around the function passed to
coroutine.start that removes the coroutine from the list, but it's pointless. There will always be an endless loop that manages the coroutines, and the lower part of that loop is a good place to check for dead coroutines.
Edited on 08 February 2014 - 02:37 AM
286 posts
Location
United States
Posted 11 February 2014 - 02:48 PM
Check out this
thread. [member='theoriginalbit'] has a coroutine management system that you can look at posted in there on pastebin, and there is discussion of it in answer to several of my questions.
54 posts
Posted 11 February 2014 - 03:09 PM
Check out this
thread. [member='theoriginalbit'] has a coroutine management system that you can look at posted in there on pastebin, and there is discussion of it in answer to several of my questions.
Ah yeah thanks for that. I have already. Its a nice example of a scheduler. I've been mucking about with a few variations of my own but I'm still a bit cloudy on what is really necessary. Let me know if you want to toss some ideas around eh? Little code collaboration for knowledge :)/>
286 posts
Location
United States
Posted 11 February 2014 - 06:37 PM
Ah yeah thanks for that. I have already. Its a nice example of a scheduler. I've been mucking about with a few variations of my own but I'm still a bit cloudy on what is really necessary. Let me know if you want to toss some ideas around eh? Little code collaboration for knowledge :)/>
The reason I mentioned the thread is that [member='theoriginalbit'] answers my questions about it in there. It is a pretty decent starting location.
For example, I learned that coroutine.yield() and os.pullEventRaw() are for all intents and purposes identical.
The basics of coroutines are pretty straight forward. Here is some testing code I wrote while just playing around with this:
-- Some function declarations
local function myFunction (someVariable)
someVariable = someVariable or "NIL"
print("In My Function: "..someVariable)
local event = {os.pullEvent("key")}
print("In Function: event=",unpack(event))
return "...Done..."
end
local myOtherFunction = function()
print("In My Other Function")
end
-- create a coroutine (does not start it)
print (type(myFunction)) --"function"
local myFirstCoRoutine = coroutine.create(myFunction)
print(type(myFirstCoRoutine)) --"thread"
print(coroutine.status(myFirstCoRoutine)) --"suspended"
-- start the coroutine
print ("Function resume return values, initial call = ",coroutine.resume(myFirstCoRoutine,"Hello",...) )-- can pass in arguments
-- will print "truekey" here because function is waiting for a key event.
print(coroutine.status(myFirstCoRoutine)) --"suspended"
repeat
local event = { coroutine.yield() }
print("In Main Event=",unpack(event))
if event[1]=="key" then -- gonna have to check here or in the thread function
print ("Function resume return values = ",coroutine.resume(myFirstCoRoutine,unpack(event)))
end
until coroutine.status(myFirstCoRoutine) == "dead"
print(coroutine.status(myFirstCoRoutine)) --"dead"