Runtime modes
Continuous running in the current thread, a background thread, or manual update.
Runtime modes
This chapter applies only to programs that need to continuously compute SDK-processed data or use background features such as automatic reconnection. When only reading raw pose/IMU, there is no need to choose a run mode, see Data channels & read methods.
When the above features are needed, choose one run mode through Glove. Do not mix them in the same run:
- Command-line programs usually call
glove.run_forever()to run continuously in the current thread; - When a GUI, an asynchronous program, or the current thread also needs to handle other work, you can call
glove.run_background()to run in the background; - When a synchronous main loop already exists, you can continuously call
glove.update()and let the program control scheduling.
Continuous running in the current thread
glove.run_forever()run_forever() blocks the current thread until a stop request is received or the SDK stops due to an error. Public command-line examples end the process with
Ctrl+C; when you need to stop actively, use background mode.
Running in a background thread
glove.run_background()
try:
...
finally:
glove.request_stop()
glove.join()join() not only waits for the thread to end, it is also responsible for reporting background running errors to the caller, so you must not call only
request_stop() and omit join(). Background mode is suitable for the GUI main thread, a host event loop, or other scenarios where the current thread cannot be blocked.
When an ordinary asyncio program reads SDK-processed data, it usually calls glove.run_background() after start(), then reads output through await output.next() or async for. The asyncio event loop itself does not advance SDK scheduling; both the SDK background run and the event loop need to keep running. close() may wait for data processing and callback cleanup, so asynchronous programs should call it through asyncio.to_thread().
If external frames come from an async iterator, you should create a separate asyncio task that continuously calls push_frame(), while reading output through await output.next() or async for. Only waiting for output without continuing to submit input frames will not produce new SDK-processed data.
Manual update
Manual mode is suitable for programs that already have a synchronous main loop and want to actively control SDK scheduling. First subscribe to the SDK-processed data, then start the device; each call to
glove.update() computes the tasks that are due, and you can also read the current output immediately through latest():
output = glove.device().output()
output.subscribe(on_output)
glove.start()
for _ in range(100):
update = glove.update()
latest = output.latest()
if latest is not None:
print(latest.sequence, latest.value)
if update.has_next_task:
update.sleep()Choose a field by what you need:
| What you want to do | Read field |
|---|---|
| Record how many scheduling rounds have run | tick |
| See how many tasks ran this time | ran_task_count |
| Decide whether to keep waiting for the next task | has_next_task |
| Wait until the next task is due | sleep() |
For complete fields, types and return values, see UpdateResult. sleep() returns
SleepResult.READY, STOPPED or NO_TASKS. Each UpdateResult can only be waited on once; reusing it or using it after the next update throws StaleUpdateError.
Manual mode only changes who advances SDK scheduling, not how data is read. A host that can coordinate SDK scheduling and the asyncio event loop by itself can also use manual update(), but must ensure that glove.update() is called continuously; only waiting for output without continuing to advance scheduling will not produce new SDK-processed data. Ordinary asynchronous programs should prefer glove.run_background(); for the asynchronous read method, see Asynchronous reading.
For a complete asynchronous flow, see async_runtime.py.