| Taskflow: A General-purpose Task-parallel Programming System

Loading...
Searching...
No Matches
Public Member Functions | List of all members
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);
);
}
tf::Worker
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() {
tf::Executor executor(4, tf::make_worker_interface<CustomWorkerBehavior>());
return 0;
}
tf::Executor
class to create an executor
Definition executor.hpp:62
tf::WorkerInterface
class to configure worker behavior in an executor
Definition worker.hpp:273
tf::WorkerInterface::scheduler_epilogue
virtual void scheduler_epilogue(Worker &worker, std::exception_ptr ptr)=0
method to call after a worker leaves the scheduling loop
tf::WorkerInterface::scheduler_prologue
virtual void scheduler_prologue(Worker &worker)=0
method to call before a worker enters the scheduling loop
tf::Worker::id
size_t id() const
queries the worker id associated with its parent executor
Definition worker.hpp:72
tf::Worker::thread
std::thread & thread()
acquires the associated thread
Definition worker.hpp:88
tf::make_worker_interface
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

  worker | a reference to the worker
  ptr | an 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

  worker | a 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:

- taskflow/core/worker.hpp