Provide an eventloop based on boost::asio.
Global Namespaces
namespace qi
Classes (namespace qi)
class qi::EventLoop
Functions (class qi::EventLoop)
Functions (namespace qi)
This eventloop consists of a threadpool of boost::asio threads waiting for
work. You can schedule work using async
or using the io_service
directly
(to do asynchronous operations on sockets for example). Most basic usages are
described in asynchronous operations.
It is often needed to schedule asynchronous work so that multiple work can be done in parallel. One way to do such a thing is to spawn a thread for the task and have the thread quit when the task is finished. It is bad practice to do such things. Spawning and exiting threads is costly in performance and must be avoided.
A threadpool starts a bunch of threads at its initialization and allows one to schedule short tasks on it, this avoids thread creations/destructions.
It is not recommended to schedule large tasks in the threadpool (like image or sound processing) since it will block a thread and be unfair to other users. Such tasks should be scheduled on separate threads (which should of course not be created/destroyed each time there is work to do) synchronized with mutexes and condition variables.
Additionally, an asynchronous task should not lock long-held mutexes or do blocking calls. Every time a task does that, a thread of the threadpool is blocked an no more work can be scheduled on it until the task finishes.
The threadpool is constantly monitored by an external thread to check if it is full (or deadlocked). The thread schedules a “ping” every 0.5 second and waits for the “pong” for 0.5 second. If it times out, a new thread is spawned until the maximum is reached. If 20 timeouts happen in a row, the emergency callback is called (which may abort execution since a deadlock is likely to have occurred).
You can control how the threadpool behaves through environment variables.
QI_EVENTLOOP_THREAD_COUNT
: number of threads the eventloop should start
with. By default, it will start with one thread per CPU. This is overridden
by calling qi::startEventLoop
explicitly.QI_EVENTLOOP_MAX_THREADS
: maximum number of threads that the threadpool can
have.QI_EVENTLOOP_GRACE_PERIOD
: time in ms to wait after a failed ping, defaults
to 0.QI_EVENTLOOP_PING_TIMEOUT
: time in ms to wait for a ping response before
considering it failed, defaults to 500.QI_EVENTLOOP_MAX_TIMEOUTS
: number of timeouts before calling the emergency
callback, defaults to 20.Class to handle eventloop. . More...
#include <qi/eventloop.hpp>
qi::ExecutionContext
async
(const boost::function<R()>& callback, uint64_t usDelay)async
(const boost::function<void()>& callback, uint64_t usDelay)async
(const boost::function<void()>& callback, qi::Duration delay)async
(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)EventLoop
(const std::string& name)~EventLoop
()isInThisContext
()start
(int nthreads)join
()stop
()setEmergencyCallback
(boost::function<void()> cb)setMaxThreads
(unsigned int max)nativeHandle
()post
(const boost::function<void()>& callback, uint64_t usDelay)post
(const boost::function<void()>& callback, qi::Duration delay)post
(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)monitorEventLoop
(EventLoop* helper, uint64_t maxUsDelay)Class to handle eventloop. .
Brief: Call given function once after given delay in microseconds.
Parameters: |
|
---|---|
Returns: | A canceleable future. |
qi::EventLoop::
async
(const boost::function<R()>& callback, uint64_t usDelay)¶Deprecateduse qi::async with qi::Duration
qi::EventLoop::
async
(const boost::function<void()>& callback, uint64_t usDelay)¶qi::EventLoop::
async
(const boost::function<void()>& callback, qi::Duration delay)¶call a callback asynchronously to be executed in delay Deprecatedsince 2.5
qi::EventLoop::
async
(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)¶call a callback asynchronously to be executed on tp Deprecatedsince 2.5
qi::EventLoop::
EventLoop
(const std::string& name = "eventloop")¶Brief: Create a new eventLoop.
Parameters: |
|
---|
You must then call either start(), run() or startThreadPool() to start event processing.
qi::EventLoop::
~EventLoop
()¶Default destructor.
qi::EventLoop::
isInThisContext
()¶Brief: Check if current thread is the event loop thread.
Returns: | true if current thread is the event loop thread. |
---|
qi::EventLoop::
start
(int nthreads = 0)¶Brief: Start the eventloop in threaded mode.
Parameters: |
|
---|
qi::EventLoop::
join
()¶Wait for run thread to terminate.
qi::EventLoop::
stop
()¶Ask main loop to terminate.
qi::EventLoop::
setEmergencyCallback
(boost::function<void()> cb)¶Brief: Set callback to be called in case of a deadlock detection.
Parameters: |
|
---|
qi::EventLoop::
setMaxThreads
(unsigned int max)¶Brief: Set the maximum number of threads in the pool.
Parameters: |
|
---|
qi::EventLoop::
nativeHandle
()¶Internal function.
qi::EventLoop::
post
(const boost::function<void()>& callback, uint64_t usDelay)¶Brief: Similar to async() but without cancelation or notification.
Parameters: |
|
---|
qi::EventLoop::
post
(const boost::function<void()>& callback, qi::Duration delay)¶qi::EventLoop::
post
(const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint)¶qi::EventLoop::
monitorEventLoop
(EventLoop* helper, uint64_t maxUsDelay)¶Brief: Monitor event loop to detect deadlocks.
Parameters: |
|
---|---|
Returns: | A canceleable future. Invoke cancel() to terminate monitoring. In case an async() call does not execute in time, the future’s error will be set. |
qi::
getEventLoop
()¶Return the global eventloop, created on demand on first call.
qi::
startEventLoop
(int nthread)¶Brief: Start the eventloop with nthread threads. No-op if already started.
Parameters: |
|
---|
qi::
getIoService
()¶Brief: Get the io_service used by the global event loop.
Returns: | io_service used by the global event loop. |
---|
qi::
async
(boost::function<R()> callback, uint64_t usDelay)¶Deprecateduse qi::async with qi::Duration
Deprecateduse qi::async with qi::Duration
qi::
async
(boost::function<R()> callback, qi::Duration delay)¶qi::
async
(boost::function<R()> callback, qi::SteadyClockTimePoint timepoint)¶