Dana Vrajitoru
B424 Parallel and Distributed Computing

Bag / Pool of Tasks

A second model with a queue of tasks

Master() {
  Queue q;
  while (tasks not finished) {
    choose randomly between
      Generate_store_task(q);
      Assign_task(q);
  }
  while (q.Not_empty())
    Assign_task(q);
  Finish_all();
}

Function generating the next task and storing it in the queue:

Generate_store_task(q) {
  task = Generate_task();
  q.enqueue(task);
}

Function collecting the result from the first process that has a result to report, getting the id of the process from the returned value, and assigning it the next task from the task queue.
Assign_task(q)
{
  worker = Collect(result, any_process);
  if (q.Is_empty())
    Generate_store_task(q);
  task = q.dequeue();
  Assign(task, worker);
}

Function Worker. It loops over reporting the result to the master, gettting a new task from the master, and executing the task, until it receives a task flagged as "none" signifying the end of the operation.

Worker() {
  result = NULL;
  do {
    Report(result, master);
    Get(task, master);
    if (task != none)
      task = Execute_task(task);
  } while (task != none);
}

The complete model

Pool of tasks, complete model

Master() {
  Queue task_q, worker_q;
  while (tasks not finished) {
    choose randomly between
      Generate_store_task(task_q);
      Get_free_worker(task_q, worker_q);
      Assign_task(task_q, worker_q);
  }
  while (!task_q.is_empty()) {
    choose randomly between
      Assign_task(task_q, worker_q); 
      Get_free_worker(task_q, worker_q);
  }
  while (worker_q.size() != nb_proc-1)
    Get_free_worker(task_q, worker_q);
  Finish_all();
}

The function Assign_task gets the next available task form the task queue and the next available worker from the worker queue (if neither of them is empty), and assigns the task to the worker.

Assign_task(task_q, worker_q)
{
  if (!task_q.is_empty() and
      !worker_q.is_empty()) {
    task = task_q.dequeue();
    worker = worker_q.dequeue();
    Assign(task, worker);
  }
}

Function collecting the result from the first process that has one to report, and enqueuing the worker that has reported the result inthe worker queue.

Get_free_worker(task_q, worker_q) 
{
  worker = Collect(result, any_process);
  worker_q.enqueue(worker);
}

Note. The implementation of this model can be a project.