This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Multi-tasking
Started by logsys, 15 July 2014 - 10:19 AMPosted 15 July 2014 - 12:19 PM
Lately, I have been trying to implement multitasking into my OS, but no success at all.. My problem is, how do I terminate a coroutine and how do I run multiple coroutines? As far as I could tell, a coroutine gets into a "standby" mode when that coroutine runs another. Can someone do a detailed tutorial for me? I always get confused with it
Posted 15 July 2014 - 09:46 PM
kinda left me confused, but im getting the handle of it.. now how do I kill a coroutine? like my program doesnt have coroutine.yield neither it ended and I want to kill it
Posted 15 July 2014 - 11:04 PM
I think you misunderstand coroutines.
Coroutines are a way to run a function, save its state, give it it's own events, and resume it later. The "own events" means that every coroutine gets its own copy of all the events.
You are probably asking for "How can the parent program terminate one of its coroutines?". That's impossible.
Let's think of a program that uses "sleep" somewhere. After the program has called the sleep function, that program pauses until the sleep ends (returns). There's no way for the program to stop that sleep. It's the same with coroutines, specifically with coroutine.resume.
—
Remember, os.pullEvent and functions that use os.pullEvent like sleep, read, turtle movement, slowprint, … ALL YIELD. If there's no such function in your program it will error: "to long without yielding", so there's probably one in your coroutine.
Coroutines are a way to run a function, save its state, give it it's own events, and resume it later. The "own events" means that every coroutine gets its own copy of all the events.
You are probably asking for "How can the parent program terminate one of its coroutines?". That's impossible.
Let's think of a program that uses "sleep" somewhere. After the program has called the sleep function, that program pauses until the sleep ends (returns). There's no way for the program to stop that sleep. It's the same with coroutines, specifically with coroutine.resume.
—
Remember, os.pullEvent and functions that use os.pullEvent like sleep, read, turtle movement, slowprint, … ALL YIELD. If there's no such function in your program it will error: "to long without yielding", so there's probably one in your coroutine.
Edited on 15 July 2014 - 09:08 PM
Posted 16 July 2014 - 12:32 AM
It's also worth noting that Lua can only do one thing at once. There's no multithreading, parallel makes it look like there is, but there isn't.
The best way in my opinion is to look at APIs or OSs that have the functionality that you want.
The best way in my opinion is to look at APIs or OSs that have the functionality that you want.
Posted 16 July 2014 - 09:11 AM
It's also worth noting that Lua can only do one thing at once. There's no multithreading, parallel makes it look like there is, but there isn't.
The best way in my opinion is to look at APIs or OSs that have the functionality that you want.
Isn't that also a property of CPU's itself? That just goes so fast you can't notice it. Or isn't that the case anymore with modern CPU's?
Posted 16 July 2014 - 09:26 AM
Modern CPUs generally have multiple physical cores - for example, a basic 3ghz dual-core system has two cores, each of which can run instructions at a rate of up to 3ghz. By spreading the load between them, they can literally process instructions in true parallel.
You might remember about ten years ago (and earlier), where if a program on your computer went haywire, it'd chew up all your system resources - meaning that the computer struggled just to get the task manager open so you could terminate the problematic process.
All that mostly went away with the rise of multi-core CPUs. This is because most programmers don't bother to write multi-threaded code, so their programs can only run on one core at a time - meaning that even if their code DOES go haywire, the other core is still free to do whatever else it is the user wants to do. In short, these CPUs are great for running multiple processor-intensive programs at the same time, but for the average user you'll never really want more than a dual.
A negative side effect is that users don't know there's a problem when a program suddenly decides to "consume" a core. Or rather, they maybe notice that the system's heating up and running its fans flat out, but since performance isn't affected they don't care.
You might remember about ten years ago (and earlier), where if a program on your computer went haywire, it'd chew up all your system resources - meaning that the computer struggled just to get the task manager open so you could terminate the problematic process.
All that mostly went away with the rise of multi-core CPUs. This is because most programmers don't bother to write multi-threaded code, so their programs can only run on one core at a time - meaning that even if their code DOES go haywire, the other core is still free to do whatever else it is the user wants to do. In short, these CPUs are great for running multiple processor-intensive programs at the same time, but for the average user you'll never really want more than a dual.
A negative side effect is that users don't know there's a problem when a program suddenly decides to "consume" a core. Or rather, they maybe notice that the system's heating up and running its fans flat out, but since performance isn't affected they don't care.
Posted 16 July 2014 - 09:26 AM
Well, multithreading's not really the correct term, but it's important to know that Lua is single threaded/what ever you want to call it. When I first started playing around with CC I didn't realise this and as a result made lots of poor design decisions.It's also worth noting that Lua can only do one thing at once. There's no multithreading, parallel makes it look like there is, but there isn't.
The best way in my opinion is to look at APIs or OSs that have the functionality that you want.
Isn't that also a property of CPU's itself? That just goes so fast you can't notice it. Or isn't that the case anymore with modern CPU's?
Posted 17 July 2014 - 07:36 PM
ok, so what ive seen from that is that coroutines cant be killed. In an normal program, without OSes, it returns "Terminated" when CTRL+T is pressed, but in normal programs they yield even if for a bit? If yes, how can I prevent it from resuming? if the program yields, in a sleep or something, will my program resumes? if yes, can I simply make it disapear with a process = nil?
Edited on 17 July 2014 - 05:36 PM
Posted 17 July 2014 - 07:50 PM
Assuming you're implementing coroutines yourself and not using the parallel api; yes, once the running program yields, control will fall back to your program, in turn you must yield, and then when you resume the program you must provide it with the event data you received (taking into consideration it's filter if it has one). As for the killing coroutines, it isn't possible. Simply remove the reference — for example routine = nil — and it will remain in a suspended status until the garbage collector comes through and destroys it (which in Minecraft is every game loop *shudders*).
I really suggest that you have a read through Bubba's# coroutine tutorial if you haven't already. As well as taking a look at how the Parallel API works.
# a.k.a. AliquotMesozoic and ChallengeMe
I really suggest that you have a read through Bubba's# coroutine tutorial if you haven't already. As well as taking a look at how the Parallel API works.
# a.k.a. AliquotMesozoic and ChallengeMe
Posted 17 July 2014 - 09:32 PM
Thank you all for your support! +1 for all of you!
Posted 18 July 2014 - 03:07 PM
As this is still open.. I will post here a question.. im since 4 hours trying to solve this error.. I have this code(code 1) to manage the coroutines.. It has worked fine when I used the code 2 that is similar to that one.. When I try to open my file browser inside LogOS, doesnt do anything.. and if I terminate with CTRL+T or the T button on the ccemuredux, it errors inside the program.. I hope you guys have time to debug my code and help me finding the error. I tried outside the OS, but it went far badly..
Here are the codes:
Here are the codes:
Code 1
function createProc(dir)
proc = {}
proc.name = fs.getName(dir)
proc.coroutine = coroutine.create(loadfile(dir))
return proc
end
function runProc(proc)
local function terminateProc(proc)
proc = nil
term.redirect(term.native())
nWindow.setVisible(false)
nWindow = nil
end
x,y = term.getSize()
nWindow = window.create(term.native(),1,2,x,y-1,true)
term.redirect(nWindow)
sFilter, arg1 = coroutine.resume(proc.coroutine)
while true do
if coroutine.status(proc.coroutine) == "dead" then
if not sFilter then term.setBackgroundColor(colors.black) print(arg1) sleep(1.2) end
terminateProc(proc)
break
end
local eventData = { os.pullEventRaw( sFilter ) }
if eventData[1] == "terminate" then
terminateProc(proc)
break
end
if eventData[1] == "mouse_click" and eventData[4] == "-1" then terminateProc(proc) break end
event, arg1 = coroutine.resume(proc.coroutine, unpack(eventData))
end
return nil
end
Code 2
function tester()
while true do
print(os.time() .. " -- Running")
coroutine.yield("mouse_click")
print(os.time() .. " -- Resumed")
end
end
coroutineA = coroutine.create(tester)
print("Preparing to resume coroutine....")
coroutine.resume(coroutineA)
while true do
arg1, arg2, arg3, arg4, arg5, arg6 = coroutine.yield(arg1)
if arg1 == "mouse_click" then
if arg4 == 1 then
--terminate
coroutineA = nil
print("Terminated")
break
else
coroutine.resume(coroutineA,arg1,arg2,arg3,arg4,arg5,arg6)
end
else
coroutine.resume(coroutineA, arg1, arg2, arg3, arg4, arg5, arg6)
end
end
Posted 18 July 2014 - 04:33 PM
Fixed that bit of code in Code 1 and the program stopped erroring… but still doesn't respond to pull events.. I already tried os.pullEvent os.pullEventRaw and coroutine.yield.. no good until nowAs this is still open.. I will post here a question.. im since 4 hours trying to solve this error.. I have this code(code 1) to manage the coroutines.. It has worked fine when I used the code 2 that is similar to that one.. When I try to open my file browser inside LogOS, doesnt do anything.. and if I terminate with CTRL+T or the T button on the ccemuredux, it errors inside the program.. I hope you guys have time to debug my code and help me finding the error. I tried outside the OS, but it went far badly..
Here are the codes:Code 1
function createProc(dir) proc = {} proc.name = fs.getName(dir) proc.coroutine = coroutine.create(loadfile(dir)) return proc end function runProc(proc) local function terminateProc(proc) proc = nil term.redirect(term.native()) nWindow.setVisible(false) nWindow = nil end x,y = term.getSize() nWindow = window.create(term.native(),1,2,x,y-1,true) term.redirect(nWindow) sFilter, arg1 = coroutine.resume(proc.coroutine) while true do if coroutine.status(proc.coroutine) == "dead" then if not sFilter then term.setBackgroundColor(colors.black) print(arg1) sleep(1.2) end terminateProc(proc) break end local eventData = { os.pullEventRaw( sFilter ) } if eventData[1] == "terminate" then terminateProc(proc) break end if eventData[1] == "mouse_click" and eventData[4] == "-1" then terminateProc(proc) break end [s]event[/s] [b]sFilter[/b], arg1 = coroutine.resume(proc.coroutine, unpack(eventData)) end return nil end
Code 2
function tester() while true do print(os.time() .. " -- Running") coroutine.yield("mouse_click") print(os.time() .. " -- Resumed") end end coroutineA = coroutine.create(tester) print("Preparing to resume coroutine....") coroutine.resume(coroutineA) while true do arg1, arg2, arg3, arg4, arg5, arg6 = coroutine.yield(arg1) if arg1 == "mouse_click" then if arg4 == 1 then --terminate coroutineA = nil print("Terminated") break else coroutine.resume(coroutineA,arg1,arg2,arg3,arg4,arg5,arg6) end else coroutine.resume(coroutineA, arg1, arg2, arg3, arg4, arg5, arg6) end end