Job

Files CCore/inc/Job.h CCore/src/Job.cpp

Files CCore/inc/Starter.h CCore/src/Starter.cpp

CCore provides a default working thread pool. You can use it on a multi-core CPU to speed-up some time-consuming calculations. To get a benefit from extra threads, you have to commit them to the pool, using the class Job::Init.


class Job::Init : NoCopy
 {
  public:
  
   static unsigned DefaultTaskCount();
  
   explicit Init(unsigned task_count=DefaultTaskCount());
   
   ~Init();
 };

It's a Scope Lock Type, constructor starts and commits working threads to the pool, destructor stops them and waits until completion. So for the scope duration the pool has committed working threads. These threads do not consume CPU, unless they are activated to do some job. Only single active Init object is allowed, an attempt to create another one will throw an exception.

To get the pool service use the class Job.


using JobType = Function<void (void)> ;

class Job : SingleHook<JobStarterType> , CustomJob
 {
  public:
  
   explicit Job(JobType job); 
   
   ~Job();
   
   class Init;
 };

First, you have to prepare some job to run. A job is represented by the JobType, which is the Function<void (void)>. Second, run the job, by creating an object of the type Job:


{
 JobType job=....;

 Job run_job(job);
}

In its constructor the Job object activates some working threads. The given job() is called in the context of each activated thread. It's also called in the current thread. Then destructor waits until all activated threads complete the call.

Sharing the job among several threads is a responsibility of the function job.

Only one JobType job can be boosted at the same time. If another Job object is created, while there is an active one, then the second will not take additional working threads.

Starter

The Job is implemented using the class Starter.


template <class T>
class Starter : public Funchor_nocopy
 {
   ....
      
  public:
  
   Starter();
   
   ~Starter();
   
   // control classes
   
   class Start;
    
   class Run;
 };

This class is a generic implementation of the working thread pool. The type T must be a lightweight functor type. It must have efficient default constructor, copy constructor and assign operator. Job uses the type JobType as the T.

There are two control classes for the Starter: Run to commit working threads to the pool and Start to use them.


template <class T>   
class Starter<T>::Run : NoCopy
 {
   ....
      
  public:
     
   explicit Run(Starter<T> &starter); 
      
   ~Run();
      
   unsigned getTaskCount() const;
 
   unsigned run(unsigned cnt);
 };

Run is bound to the given Starter.

getTaskCount() returns the number of committed to the starter threads.

run() commits additional cnt threads. It returns getTaskCount().

Only single Run per Starter is allowed.


template <class T>   
class Starter<T>::Start : NoCopy
 {
   .... 
      
  public: 
     
   Start(Starter<T> *starter,const T &obj); 
    
   ~Start(); 
   
   bool operator + () const;
    
   bool operator ! () const;
 };

Start tries to get the Starter service. If the starter is not null and in the idle state, then the constructor commits obj for execution. Available working threads from the pool will call obj(). There may be zero such threads. Destructor waits until all activated threads complete the call.

operator + and operator ! can be used to check, if the job was successfully started.