Tasking Overview¶
Overview¶
In a world of increasing multi-processing computing, it is important to take advantage of additional CPUs to perform parallel work. However, creating threads is tedious and individual threads have a cost to start and tear down. It is therefore highly recommended to create a pool of threads to perform a vast array of small individual tasks. Enter the carb.tasking plugin.
Quick Start¶
The carb.tasking plugin is very powerful, but can be very simple to use. Similar to std::thread
, nearly all of the
carb::tasking::ITasking::addTask()
variant functions support std::invoke
-style bind parameters. They can be given
functors, function pointers, member-function pointers, or lambdas. Here is a simple example of queuing a lambda:
auto tasking = carb::getCachedInterface<carb::tasking::ITasking>();
auto future = tasking->addTask(carb::tasking::Priority::eDefault, {}, [] {
// This runs in a fiber within a task thread!
requestSomethingAsync();
// Suspend ourself until a result is ready
tasking->suspendTask();
// Woken with wakeTask()! Return the result.
return getAsyncResult();
});
doSomethingElse();
// Wait for the task to complete and return
auto result = future.get();
You could even create many hundreds or thousands of “persistent tasks”–tasks that run periodically, then sleep for a bit:
tasking->addTask(carb::tasking::Priority::eDefault, {}, &NPC::brain, this);
void NPC::brain()
{
while (!done)
{
// Do thinking for this NPC
think();
// Wait until the next time we should wake up and think
tasking->sleep_for(std::chrono::milliseconds(100));
}
}
Architecture¶
ITasking is a fiber-based tasking system. This means that each task you add to the system has its own full stack until the task ends. This also means that tasks have a rich functionality feature-set and can do things like block on I/O or sleep without affecting a thread of execution.