Back to Taskflow

tf::WorkerInterface class

docs/classtf_1_1WorkerInterface.html

4.0.04.4 KB
Original Source

tf::WorkerInterface class

class to configure worker behavior in an executor

The tf::WorkerInterface class allows users to customize worker properties when creating an executor. Examples include binding workers to specific CPU cores or invoking custom methods before and after a worker enters or leaves the work-stealing loop. When you create an executor, it spawns a set of workers to execute tasks with the following logic:

for(size\_t n=0; n\<num\_workers; n++) {create\_thread([](Worker& worker)// enter the scheduling loop// Here, WorkerInterface::scheduler\_prologue is invoked, if anyworker\_interface-\>scheduler\_prologue(worker);try {while(1) {perform\_work\_stealing\_algorithm();if(stop) {break;}}} catch(...) {exception\_ptr = std::current\_exception();}// leaves the scheduling loop and joins this worker thread// Here, WorkerInterface::scheduler\_epilogue is invoked, if anyworker\_interface-\>scheduler\_epilogue(worker, exception\_ptr););}

The example below demonstrates the usage of tf::WorkerInterface to affine a worker to a specific CPU core equal to its id on a Linux platform:

// affine the given thread to the given core index (linux-specific)bool affine(std::thread& thread, unsigned int core\_id) {cpu\_set\_t cpuset;CPU\_ZERO(&cpuset);CPU\_SET(core\_id, &cpuset);pthread\_t native\_handle = thread.native\_handle();return pthread\_setaffinity\_np(native\_handle, sizeof(cpu\_set\_t), &cpuset) == 0;}class CustomWorkerBehavior : public tf::WorkerInterface {public:// to call before the worker enters the scheduling loopvoid scheduler\_prologue(tf::Worker& w) override {printf("worker %lu prepares to enter the work-stealing loop\n", w.id());// now affine the worker to a particular CPU core equal to its idif(affine(w.thread(), w.id())) {printf("successfully affines worker %lu to CPU core %lu\n", w.id(), w.id());}else {printf("failed to affine worker %lu to CPU core %lu\n", w.id(), w.id());}}// to call after the worker leaves the scheduling loopvoid scheduler\_epilogue(tf::Worker& w, std::exception\_ptr) override {printf("worker %lu left the work-stealing loop\n", w.id());}};int main() {tf::Executor executor(4, tf::make\_worker\_interface\<CustomWorkerBehavior\>());return 0;}

When running the program, we see the following one possible output:

worker3prepares to enter the work-stealing loop
successfully affines worker3to CPU core3worker3left the work-stealing loop
worker0prepares to enter the work-stealing loop
successfully affines worker0to CPU core0worker0left the work-stealing loop
worker1prepares to enter the work-stealing loop
worker2prepares to enter the work-stealing loop
successfully affines worker1to CPU core1worker1left the work-stealing loop
successfully affines worker2to CPU core2worker2left the work-stealing loop

Constructors, destructors, conversion operators

~WorkerInterface() defaulted virtualdefault destructor

Public functions

void scheduler_prologue(Worker& worker) pure virtualmethod to call before a worker enters the scheduling loopvoid scheduler_epilogue(Worker& worker, std::exception_ptr ptr) pure virtualmethod to call after a worker leaves the scheduling loop

Function documentation

void tf::WorkerInterface::scheduler_prologue(Worker& worker) pure virtual

method to call before a worker enters the scheduling loop

Parameters
worker

The method is called by the scheduler before entering the work-stealing loop.

void tf::WorkerInterface::scheduler_epilogue(Worker& worker, std::exception_ptr ptr) pure virtual

method to call after a worker leaves the scheduling loop

Parameters
worker
ptr

The method is called by the scheduler after leaving the work-stealing loop. Any uncaught exception during the worker's execution will be propagated through the given exception pointer.