FRAMES NO FRAMES

Class IlcWorkServer

Definition file: ilsched/workserv.h
Include file: <ilsched/workserv.h>

This class offers facilities for writing multi-threaded applications. It allows you to create a specified number of threads and then to execute different pieces of code on these threads asynchronously. Each thread is associated with a unique environment that is an instance of IloEnv; the code executed by each thread is a Solver goal.

Upon request, the workserver object provides you with the environment or solver of a thread waiting for work. An instance of IloGoal can be constructed in the environment. It can then be extracted to the solver of the corresponding thread and executed on the thread.

For more information, see Durability.

See Also:

Constructor Summary
public IlcWorkServer()
public IlcWorkServer(IlcBaseAgentServerI * impl)
public IlcWorkServer(const IlcScheduler sched0, IlcInt nbOfThreads, const char * prefix=0)
Method Summary
public voidend()
public IloEnvgetIdleEnv()
public IloSolvergetIdleSolver()
public IlcBaseAgentServerI *getImpl() const
public voidlaunch(IloGoal goal)
public voidoperator=(const IlcWorkServer & h)
Constructor Detail

IlcWorkServer

public IlcWorkServer()

This constructor creates an empty handle. You must initialize it before you use it.


IlcWorkServer

public IlcWorkServer(IlcBaseAgentServerI * impl)

This constructor creates a handle object from a pointer to an implementation object.


IlcWorkServer

public IlcWorkServer(const IlcScheduler sched0, IlcInt nbOfThreads, const char * prefix=0)

This constructor creates a work server that starts nbOfThreads worker threads. Each worker thread has a different environment and waits to receive work. If the number of threads is 0, then no worker thread is created and further calls to the member function launch of this IlcWorkServer will be treated sequentially.

The created work server will be used to solve solver goals that use the durable resources of the schedule sched0. Note that sched0 must be a durable and closed schedule. If sched0 is not a durable schedule or is not closed, any attempt to launch a goal on this work server will raise an error.

The argument prefix serves as a base for creating names for the output streams of each thread: the first thread will output in prefix0.out, the second in prefix1.out, etc. If prefix is 0, then the default output stream is considered.

Note
An application containing a workserver object can be compiled as a single threaded application. In this case, the actual value of the parameter nbOfThreads is ignored and is considered to be zero.

Method Detail

end

public void end()

This member function waits for all worker threads to finish their work, then stops them and calls end() on each worker's environment.


getIdleEnv

public IloEnv getIdleEnv()

This member function returns the environment associated with a thread that is waiting for work. If there is no such thread, this call may block while waiting for a free worker.


getIdleSolver

public IloSolver getIdleSolver()

This member function returns the solver associated with a thread that is waiting for work. If there is no such thread, this call may block while waiting for a free worker.


getImpl

public IlcBaseAgentServerI * getImpl() const
This constructor creates an object by copying another one.

This member function returns a pointer to the implementation object of the invoking handle.


launch

public void launch(IloGoal goal)

The argument goal must be a solver goal constructed on the same environment as the solver obtained by a previous call to getIdleSolver. The waiting worker whose solver was returned by the previous call at getIdleSolver starts working by extracting and executing the goal. Calls to getIdleSolver and launch must be interleaved. At the end of the execution of the goal, the memory allocated on the idle solver is collected.

Example

Let us consider the very simple scheduling problem that consists of creating and scheduling an activity which requires a given durable resource. Suppose that ten instances of this problem are to be solved, each instance characterized by the particular resource it needs. The inherent parallelism of this application can by exploited by solving different instances on different threads.

The following Solver goal defines and solves an instance of the scheduling problem.

#include <ilsched/iloscheduler.h>
#include <ilsched/workserv.h>

 ILCGOAL1(ProblemIlc,
 	 IlcDiscreteResource, resource) {
   IloSolver solver = getSolver();
   IlcSchedule schedule(solver, 0, 365);
   IlcActivity activity(scheduler, 10);
   scheduler.lock(1, resource);
   solver.add(activity.requires(resource, 3));
   solver.startNewSearch(IlcSetTimes(schedule));
   solver.next();
   schedule.unlock(1, resource);
   solver.endSearch();
   return 0;
 }

 ILOCPGOALWRAPPER2(Problem, solver,
 		  IlcScheduler, durableSched,
 		  IloDiscreteResource, resource) {
   return ProblemIlc(solver,
 		    durableSched.getDiscreteResource(resource));
 }

 int main(){

   // Creating the durable resources in a model:
   IloEnv env0;
   IloModel model0(env0);
   const IloInt nbOfResources = 2;
   IloDiscreteResource resources[nbOfResources];
   for (IloInt i=0; i < nbOfResources; i++) {
     resources[i] = IloDiscreteResource(env0, 7);
     model0.add(resources[i]);
   }

   // Creating the durable scheduler:
   IloSolver solver0(env0);
   IlcScheduler scheduler0(solver0);
   scheduler0.setDurable();
   solver0.extract(model0);
   scheduler0.close();

   // Creating the worker threads:
   IlcWorkServer server(scheduler0, 3);

   // Solving ten instances:
   for (IloInt k=0; k<10; k++){
     IloInt resourceIdx = k % nbOfResources;

     // Getting the solver of a waiting worker thread:
     IloEnv env = server.getIdleEnv();

     // Creating the problem instance:
     IloGoal instance = Problem(env,
 			       scheduler0,
 			       resources[resourceIdx]);

    // Solving it on the corresponding thread:
     server.launch(instance);
   }

   // Stopping all worker threads:
   server.end();
   env0.end();
   return 0;
 }

operator=

public void operator=(const IlcWorkServer & h)

This operator assigns an address to the handle pointer of the invoking object. That address is the location of the implementation object of the provided argument.