parallel
A simple way to run several functions at once.
Functions are not actually executed simultaneously, but rather this API will
automatically switch between them whenever they yield (e.g. whenever they call
coroutine.yield, or functions that call that - such as os.pullEvent - or
functions that call that, etc - basically, anything that causes the function
to "pause").
Each function executed in "parallel" gets its own copy of the event queue,
and so "event consuming" functions (again, mostly anything that causes the
script to pause - eg os.sleep, rednet.receive, most of the turtle API,
etc) can safely be used in one without affecting the event queue accessed by
the other.
warning
When using this API, be careful to pass the functions you want to run in parallel, and not the result of calling those functions.
For instance, the following is correct:
local function do_sleep() sleep(1) end parallel.waitForAny(do_sleep, rednet.receive)
but the following is NOT:
local function do_sleep() sleep(1) end parallel.waitForAny(do_sleep(), rednet.receive)
Changes
- New in version 1.2
| waitForAny(...) | Switches between execution of the functions, until any of them finishes. |
|---|---|
| waitForAll(...) | Runs several functions in parallel, until all of them are finished. |
- waitForAny(...)Source
Switches between execution of the functions, until any of them finishes. If any of the functions errors, the message is propagated upwards from the
parallel.waitForAnycall.Parameters
- ...
functionThe functions to run in parallel.
Usage
Print a message every second until the
qkey is pressed.local function tick() while true do os.sleep(1) print("Tick") end end local function wait_for_q() repeat local _, key = os.pullEvent("key") until key == keys.q print("Q was pressed!") end parallel.waitForAny(tick, wait_for_q) print("Everything done!")
- ...
- waitForAll(...)Source
Runs several functions in parallel, until all of them are finished.
If any of the functions errors, the other functions are not resumed, and the error is propagated upwards.
warning
While any number of functions can be run in parallel, running too many things in parallel can sometimes cause issues:
- Computers only buffer 256 events at a time. Trying to run several hundred functions in parallel (particularly when calling peripheral methods) can cause the event queue to fill up, resulting in events being dropped, and programs getting stuck.
- Computers only run 16 HTTP requests at a time. Trying to run more than that in parallel will have no effect.
Spawning new parallel functions
In some cases, you may want to start running additional functions in parallel from an existing
parallel.waitForAllcall. Every function passed towaitForAllcan accept aspawnargument, which can be called to spawn new parallel functions.parallel.waitForAll(function(spawn) spawn(function() sleep(1); print("Finished 1") end) spawn(function() sleep(2); print("Finished 2") end) end)
Parameters
- ... function(spawn: function(fn:
function, ...:any)) The functions to run in parallel.
Usage
Start off two timers and wait for them both to run.
local function a() os.sleep(1) print("A is done") end local function b() os.sleep(3) print("B is done") end parallel.waitForAll(a, b) print("Everything done!")
Generate a list of functions to run in parallel.
local funcs = {} for i = 1, 5 do table.insert(funcs, function() sleep(math.random()) print("Finished " .. i) end) end parallel.waitForAll(table.unpack(funcs)) print("Everything done!")
Run new functions in parallel from within
waitForAll.parallel.waitForAll(function(spawn) for i = 1, 5 do spawn(function() sleep(math.random()) print("Finished " .. i) end) end end) print("Everything done!")
Changes
- Changed in version 1.120.0: Added ability to spawn new parallel functions.