Loading...
Searching...
No Matches
tf::WorkerInterface Class Referenceabstract

class to configure worker behavior in an executor More...

#include <taskflow/core/worker.hpp>

Public Member Functions

virtual ~WorkerInterface ()=default
 default destructor
 
virtual void scheduler_prologue (Worker &worker)=0
 method to call before a worker enters the scheduling loop
 
virtual void scheduler_epilogue (Worker &worker, std::exception_ptr ptr)=0
 method to call after a worker leaves the scheduling loop
 

Detailed Description

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 any
worker_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 any
worker_interface->scheduler_epilogue(worker, exception_ptr);
);
}
class to create a worker in an executor
Definition worker.hpp:55

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 loop
void 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 id
if(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 loop
void scheduler_epilogue(tf::Worker& w, std::exception_ptr) override {
printf("worker %lu left the work-stealing loop\n", w.id());
}
};
int main() {
return 0;
}
class to configure worker behavior in an executor
Definition worker.hpp:273
virtual void scheduler_epilogue(Worker &worker, std::exception_ptr ptr)=0
method to call after a worker leaves the scheduling loop
virtual void scheduler_prologue(Worker &worker)=0
method to call before a worker enters the scheduling loop
size_t id() const
queries the worker id associated with its parent executor
Definition worker.hpp:70
std::thread & thread()
acquires the associated thread
Definition worker.hpp:86
std::shared_ptr< T > make_worker_interface(ArgsT &&... args)
helper function to create an instance derived from tf::WorkerInterface
Definition worker.hpp:312

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

worker 3 prepares to enter the work-stealing loop
successfully affines worker 3 to CPU core 3
worker 3 left the work-stealing loop
worker 0 prepares to enter the work-stealing loop
successfully affines worker 0 to CPU core 0
worker 0 left the work-stealing loop
worker 1 prepares to enter the work-stealing loop
worker 2 prepares to enter the work-stealing loop
successfully affines worker 1 to CPU core 1
worker 1 left the work-stealing loop
successfully affines worker 2 to CPU core 2
worker 2 left the work-stealing loop
Attention
tf::WorkerInterface::scheduler_prologue and tf::WorkerInterface::scheduler_epologue are invoked by each worker simultaneously.

Member Function Documentation

◆ scheduler_epilogue()

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

method to call after a worker leaves the scheduling loop

Parameters
workera reference to the worker
ptran pointer to the exception thrown by the scheduling loop

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.

◆ scheduler_prologue()

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

method to call before a worker enters the scheduling loop

Parameters
workera reference to the worker

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


The documentation for this class was generated from the following file: