📦 marl/ google
A hybrid thread / fiber task scheduler written in C++ 11
Установка и запуск
Usage Recommendations
Capture marl synchronization primitives by value
All marl synchronization primitives aside from marl::ConditionVariable should be lambda-captured by value:
marl::Event event;
marl::schedule([=]{ // [=] Good, [&] Bad.
event.signal();
})
Internally, these primitives hold a shared pointer to the primitive state. By capturing by value we avoid common issues where the primitive may be destructed before the last reference is used.
Create one instance of marl::Scheduler, use it for the lifetime of the process
The marl::Scheduler constructor can be expensive as it may spawn a number of hardware threads.
Destructing the marl::Scheduler requires waiting on all tasks to complete.
Multiple marl::Schedulers may fight each other for hardware thread utilization.
For these reasons, it is recommended to create a single marl::Scheduler for the lifetime of your process.
For example:
int main() {
marl::Scheduler scheduler(marl::Scheduler::Config::allCores());
scheduler.bind();
defer(scheduler.unbind());
return do_program_stuff();
}
Bind the scheduler to externally created threads
In order to call marl::schedule() the scheduler must be bound to the calling thread. Failure to bind the scheduler to the thread before calling marl::schedule() will result in undefined behavior.
marl::Scheduler may be simultaneously bound to any number of threads, and the scheduler can be retrieved from a bound thread with marl::Scheduler::get().
A typical way to pass the scheduler from one thread to another would be:
std::thread spawn_new_thread() {
// Grab the scheduler from the currently running thread.
marl::Scheduler* scheduler = marl::Scheduler::get();
…
Из README репозитория · полный README на GitHub