scheduler
The scheduler module provides coroutine scheduling functionality for managing coroutine creation, execution, synchronization, and communication. This is an extension module of xmake.
NOTE
To use this module, you need to import it first: import("core.base.scheduler")
scheduler.co_start
- Start a new coroutine task
import("core.base.scheduler")
local co = scheduler.co_start(function()
print("Hello from coroutine!")
end)
Start a new coroutine and execute the specified task function. The coroutine will start executing immediately unless the scheduler is not yet started.
Parameters:
cotask
- Required. The coroutine task function to execute...
- Optional. Arguments to pass to the task function
Return value:
- Returns coroutine object on success, nil and error message on failure
-- Start coroutine with arguments
local co = scheduler.co_start(function(name, id)
print("Task", name, "with id", id, "started")
end, "worker", 123)
-- Coroutine group example
local count = 0
scheduler.co_group_begin("test", function()
for i = 1, 100 do
scheduler.co_start(function()
count = count + 1
end)
end
end)
scheduler.co_group_wait("test")
print("Completed", count, "tasks")
scheduler.co_start_named
- Start a named coroutine task
import("core.base.scheduler")
local co = scheduler.co_start_named("worker", function()
print("Named coroutine started")
end)
Start a coroutine task with a specified name for easier debugging and monitoring.
Parameters:
coname
- Required. Coroutine namecotask
- Required. The coroutine task function to execute...
- Optional. Arguments to pass to the task function
-- Start multiple named coroutines
for i = 1, 5 do
scheduler.co_start_named("worker-" .. i, function()
print("Worker", i, "started")
scheduler.co_sleep(1000)
print("Worker", i, "finished")
end)
end
scheduler.co_start_withopt
- Start a coroutine task with options
import("core.base.scheduler")
local co = scheduler.co_start_withopt({
name = "isolated-worker",
isolate = true
}, function()
print("Isolated coroutine started")
end)
Start a coroutine task with specific options.
Parameters:
opt
- Required. Coroutine options tablecotask
- Required. The coroutine task function to execute...
- Optional. Arguments to pass to the task function
opt
options:
name
- Coroutine nameisolate
- Whether to isolate coroutine environment (default false)
-- Start coroutine with isolated environment
local co = scheduler.co_start_withopt({
name = "isolated-task",
isolate = true
}, function()
-- This coroutine has independent environment variables
os.setenv("CUSTOM_VAR", "isolated_value")
print("Isolated task running")
end)
scheduler.co_suspend
- Suspend the current coroutine
import("core.base.scheduler")
function task()
print("Task started")
scheduler.co_suspend() -- Suspend coroutine
print("Task resumed")
end
Suspend the currently executing coroutine and yield execution to other coroutines.
Return value:
- Returns arguments passed to
co_resume
local co = scheduler.co_start(function()
print("Step 1")
scheduler.co_suspend()
print("Step 2")
end)
-- Coroutine will suspend at co_suspend()
-- Can be resumed with co_resume
scheduler.co_resume
- Resume a suspended coroutine
import("core.base.scheduler")
local co = scheduler.co_start(function()
local value = scheduler.co_suspend()
print("Resumed with value:", value)
end)
-- Resume coroutine and pass arguments
scheduler.co_resume(co, "hello")
Resume the specified suspended coroutine and optionally pass arguments to it.
Parameters:
co
- Required. The coroutine object to resume...
- Optional. Arguments to pass to the coroutine
-- Coroutine communication example
local co = scheduler.co_start(function()
local data = scheduler.co_suspend()
print("Received data:", data)
local result = "processed: " .. data
scheduler.co_suspend(result)
end)
-- Send data and get result
scheduler.co_resume(co, "input data")
local result = scheduler.co_resume(co)
print("Got result:", result)
scheduler.co_yield
- Yield execution of the current coroutine
import("core.base.scheduler")
function task()
for i = 1, 5 do
print("Task step", i)
scheduler.co_yield() -- Yield execution
end
end
Yield execution of the current coroutine to allow other coroutines to run. This is a key function for cooperative multitasking.
-- Cooperative task example
scheduler.co_group_begin("cooperative", function()
for i = 1, 3 do
scheduler.co_start(function(id)
for j = 1, 3 do
print("Task", id, "step", j)
scheduler.co_yield()
end
end, i)
end
end)
scheduler.co_group_wait("cooperative")
scheduler.co_sleep
- Sleep the coroutine for specified time
import("core.base.scheduler")
function delayed_task()
print("Task started")
scheduler.co_sleep(1000) -- Sleep for 1 second
print("Task resumed after sleep")
end
Make the current coroutine sleep for the specified number of milliseconds, during which other coroutines can continue executing.
Parameters:
ms
- Required. Sleep time in milliseconds, 0 means no sleep
-- Timed task example
for i = 1, 5 do
scheduler.co_start(function(id)
print("Task", id, "starting")
scheduler.co_sleep(id * 500) -- Incremental delay
print("Task", id, "finished")
end, i)
end
scheduler.co_lock
- Lock the specified lock
import("core.base.scheduler")
function critical_section()
scheduler.co_lock("shared_resource")
print("Entering critical section")
-- Critical section code
scheduler.co_unlock("shared_resource")
print("Leaving critical section")
end
Acquire the lock with the specified name. If the lock is already held by another coroutine, the current coroutine will wait until the lock becomes available.
Parameters:
lockname
- Required. The name of the lock
-- Mutex lock example
local shared_counter = 0
for i = 1, 10 do
scheduler.co_start(function(id)
scheduler.co_lock("counter")
local old_value = shared_counter
scheduler.co_sleep(100) -- Simulate work
shared_counter = old_value + 1
print("Task", id, "incremented counter to", shared_counter)
scheduler.co_unlock("counter")
end, i)
end
scheduler.co_unlock
- Release the specified lock
import("core.base.scheduler")
function critical_section()
scheduler.co_lock("my_lock")
-- Critical section code
scheduler.co_unlock("my_lock")
end
Release the lock with the specified name, allowing other waiting coroutines to acquire the lock.
Parameters:
lockname
- Required. The name of the lock to release
scheduler.co_group_begin
- Begin a coroutine group
import("core.base.scheduler")
scheduler.co_group_begin("workers", function(group)
-- All coroutines started in this scope will join the group
for i = 1, 5 do
scheduler.co_start(function()
print("Worker", i, "started")
end)
end
end)
Begin a new coroutine group. All coroutines started within the specified function will join this group.
Parameters:
name
- Required. The coroutine group namescopefunc
- Required. The scope function
-- Batch job processing example
scheduler.co_group_begin("batch_jobs", function()
local jobs = {"job1", "job2", "job3", "job4", "job5"}
for i, job in ipairs(jobs) do
scheduler.co_start(function(job_name)
print("Processing", job_name)
scheduler.co_sleep(math.random(100, 500))
print("Completed", job_name)
end, job)
end
end)
scheduler.co_group_wait
- Wait for coroutine group completion
import("core.base.scheduler")
scheduler.co_group_begin("test", function()
for i = 1, 10 do
scheduler.co_start(function()
print("Task", i, "completed")
end)
end
end)
-- Wait for all coroutines to complete
scheduler.co_group_wait("test")
print("All tasks completed")
Wait for all coroutines in the specified group to complete execution.
Parameters:
name
- Required. The coroutine group nameopt
- Optional. Wait options
opt
options:
limit
- Maximum number of coroutines to wait for completion (default wait for all coroutines)
-- Limited wait example
scheduler.co_group_begin("limited", function()
for i = 1, 10 do
scheduler.co_start(function(id)
print("Task", id, "running")
scheduler.co_sleep(id * 100)
print("Task", id, "finished")
end, i)
end
end)
-- Only wait for first 3 coroutines to complete
scheduler.co_group_wait("limited", {limit = 3})
print("First 3 tasks completed")
scheduler.co_running
- Get the currently running coroutine
import("core.base.scheduler")
function task()
local co = scheduler.co_running()
if co then
print("Current coroutine name:", co:name())
print("Current coroutine status:", co:status())
end
end
Get the currently running coroutine object.
Return value:
- Current coroutine object, or nil if no coroutine is running
-- Coroutine info example
scheduler.co_start_named("info_task", function()
local co = scheduler.co_running()
print("Coroutine name:", co:name())
print("Coroutine status:", co:status())
print("Is dead:", co:is_dead())
print("Is running:", co:is_running())
print("Is suspended:", co:is_suspended())
end)
scheduler.co_count
- Get the total number of coroutines
import("core.base.scheduler")
print("Total coroutines:", scheduler.co_count())
Get the total number of active coroutines in the current scheduler.
Return value:
- Number of coroutines
-- Coroutine counting example
print("Initial count:", scheduler.co_count())
for i = 1, 5 do
scheduler.co_start(function()
print("Task", i, "started, count:", scheduler.co_count())
scheduler.co_sleep(1000)
print("Task", i, "finished, count:", scheduler.co_count())
end)
end
print("After starting tasks:", scheduler.co_count())
scheduler.co_semaphore
- Create a coroutine semaphore
import("core.base.scheduler")
local semaphore = scheduler.co_semaphore("test", 2) -- Initial value is 2
Create a new coroutine semaphore for synchronization and resource control between coroutines.
Parameters:
name
- Required. Semaphore namevalue
- Optional. Initial semaphore value (default 0)
Return value:
- Semaphore object
-- Semaphore example
local semaphore = scheduler.co_semaphore("resource", 3) -- Allow up to 3 coroutines simultaneously
for i = 1, 10 do
scheduler.co_start(function(id)
print("Task", id, "waiting for resource")
local value = semaphore:wait(-1) -- Wait indefinitely
print("Task", id, "got resource, value:", value)
scheduler.co_sleep(1000) -- Simulate work
semaphore:post(1) -- Release resource
print("Task", id, "released resource")
end, i)
end
co_semaphore:wait
- Wait for semaphore
import("core.base.scheduler")
local semaphore = scheduler.co_semaphore("test", 1)
local value = semaphore:wait(5000) -- Wait for 5 seconds
Wait for the semaphore. If the semaphore value is greater than 0, return immediately; otherwise, suspend the current coroutine until the semaphore becomes available.
Parameters:
timeout
- Optional. Timeout in milliseconds, -1 means wait indefinitely, 0 means don't wait
Return value:
- Returns semaphore value on success, 0 on timeout, -1 on error
-- Semaphore wait example
local semaphore = scheduler.co_semaphore("worker", 0)
-- Producer coroutine
scheduler.co_start(function()
for i = 1, 5 do
scheduler.co_sleep(1000)
semaphore:post(1)
print("Posted signal", i)
end
end)
-- Consumer coroutine
scheduler.co_start(function()
for i = 1, 5 do
local value = semaphore:wait(-1)
print("Got signal", i, "value:", value)
end
end)
co_semaphore:post
- Release semaphore
import("core.base.scheduler")
local semaphore = scheduler.co_semaphore("test", 0)
local new_value = semaphore:post(2) -- Increase by 2
Release the semaphore by increasing its value and wake up waiting coroutines.
Parameters:
value
- Required. The value to increase by
Return value:
- The new semaphore value after release
-- Semaphore post example
local semaphore = scheduler.co_semaphore("batch", 0)
-- Batch processing example
scheduler.co_start(function()
scheduler.co_sleep(2000)
print("Batch processing started")
semaphore:post(5) -- Release 5 signals at once
end)
for i = 1, 5 do
scheduler.co_start(function(id)
local value = semaphore:wait(-1)
print("Worker", id, "got batch signal, value:", value)
end, i)
end
co_semaphore:name
- Get semaphore name
import("core.base.scheduler")
local semaphore = scheduler.co_semaphore("my_semaphore", 1)
print("Semaphore name:", semaphore:name())
Get the semaphore name.
Return value:
- Semaphore name string