IBM ILOG Scheduler User's Manual > Integrated Applications > Writing Multi-Threaded Applications Using Durable Resources > Solving The Problem

There are a few differences in the code when compared to Chapter 22. One difference is that closing the durable schedule now becomes mandatory. Closing a durable schedule ensures that no further durable resources will be created. The durable schedule can be closed at the end of the function CreateDurableResources.

IlcScheduler CreateDurableResources(IloSolver solver0,
                                    IloInt nbOfWorkers,
                                    IloUnaryResource* workers) {
  /* CREATE A DURABLE MODEL. */
  IloEnv env0 = solver0.getEnv();
  IloModel model0(env0);
  IloSchedulerEnv schedEnv0(env0);
 
  IloIntervalList blist(env0, 0, 100);
  blist.addPeriodicInterval(5, 2, 7, 100);
  schedEnv0.setBreakListParam(blist);
 
  IlcInt i=0;
  for (i = 0; i < nbOfWorkers; i++){
    workers[i] = IloUnaryResource(env0);
    model0.add(workers[i]);
  }
 
  IlcScheduler durSched(solver0);
  durSched.setDurable();
  solver0.extract(model0);
 
  /* CLOSE THE DURABLE SCHEDULER. */
  durSched.close(); 
 
  return durSched;
}
 

The treatment of a request by an operator remains made by the goal TreatRequest.

ILCGOAL3(TreatRequestIlc,
         IlcInt, reqIndex,
         IlcUnaryResource*, team,
         IlcInt, releaseDate){


A given number of threads are created by constructing an object of type IlcWorkServer. The first thread prints the output in the file called output0.out, the second in the file output1.out, etc.

    /* CREATING THE WORKER THREADS. */
    IloInt nbOfThreads = 3;
    if (argc >= 2)
      nbOfThreads = atol(argv[1]);
    IlcWorkServer server(sched0, nbOfThreads, "output");

The main loop of the application reads requests one by one from the input stream of requests and dispatches them to be treated on different threads. At each iteration, you must get the environment of an available thread, construct the goal TreatRequest for that environment, and launch the request treatment. The goal is then extracted to the solver associated to the corresponding thread and its code is executed asynchronously on the thread.

In this case, you don't have to delete the environment of the used solver, as its memory is managed by the IlcWorkServer object.

    /* TREATING THE REQUESTS. */
    for (IloInt j = 0; j < HowManyReqs; j++) {
      // Reading a request :
      IloInt requestType = StreamOfReqs[j][0];
      IloInt releaseDate = StreamOfReqs[j][1];

      // Getting a computation environment :
      IloEnv env = server.getIdleEnv();
      // Solving the specific problem associated with the request:
      IloUnaryResource* team = (requestType == 1 ?
                                firstTeam :
                                secondTeam);
      server.launch(TreatRequest(env, sched0, j, team, releaseDate));
    }

After all requests are processed, the threads are stopped by deleting the IlcWorkServer object.

    /* STOPPING THE WORKER THREADS. */
    server.end();