Читаем Thinking In C++. Volume 2: Practical Programming полностью

  void run() {

    try {

      while(!Thread::interrupted()) {

        // Blocks until job is offered/accepted:

        cradle->offerEngineBotServices();

        cout << "Installing engine" << endl;

        (*cradle)->addEngine();

        cradle->taskFinished();

      }

    } catch(Interrupted_Exception&) { /* Exit */ }

    cout << "EngineRobot off" << endl;

  }

};


class DriveTrainRobot : public Runnable {

  CradlePtr cradle;

public:

  DriveTrainRobot(CradlePtr cr) : cradle(cr) {}

  void run() {

    try {

      while(!Thread::interrupted()) {

        // Blocks until job is offered/accepted:

        cradle->offerDriveTrainBotServices();

        cout << "Installing DriveTrain" << endl;

        (*cradle)->addDriveTrain();

        cradle->taskFinished();

      }

    } catch(Interrupted_Exception&) { /* Exit */ }

    cout << "DriveTrainRobot off" << endl;

  }

};


class WheelRobot : public Runnable {

  CradlePtr cradle;

public:

  WheelRobot(CradlePtr cr) : cradle(cr) {}

  void run() {

    try {

      while(!Thread::interrupted()) {

        // Blocks until job is offered/accepted:

        cradle->offerWheelBotServices();

        cout << "Installing Wheels" << endl;

        (*cradle)->addWheels();

        cradle->taskFinished();

      }

    } catch(Interrupted_Exception&) { /* Exit */ }

    cout << "WheelRobot off" << endl;

  }

};


class Reporter : public Runnable {

  CarQueue carQueue;

public:

  Reporter(CarQueue& cq) : carQueue(cq) {}

  void run() {

    try {

      while(!Thread::interrupted()) {

        cout << carQueue->get() << endl;

      }

    } catch(Interrupted_Exception&) { /* Exit */ }

    cout << "Reporter off" << endl;

  }

};


int main() {

  cout << "Press to quit" << endl;

  try {

    CarQueue chassisQueue(new TQueue),

             finishingQueue(new TQueue);

    CradlePtr cradle(new Cradle);

    ThreadedExecutor assemblyLine;

    assemblyLine.execute(new EngineRobot(cradle));

    assemblyLine.execute(new DriveTrainRobot(cradle));

    assemblyLine.execute(new WheelRobot(cradle));

    assemblyLine.execute(

      new Director(chassisQueue, finishingQueue, cradle));

    assemblyLine.execute(new Reporter(finishingQueue));

    // Start everything running by producing chassis:

    assemblyLine.execute(new ChassisBuilder(chassisQueue));

    cin.get();

    assemblyLine.interrupt();

  } catch(Synchronization_Exception& e) {

    cerr << e.what() << endl;

  }

} ///:~


You’ll notice that Car takes a shortcut: it assumes that bool operations are atomic, which, as previously discussed, is generally a safe assumption but one to consider carefully. Each Car begins as an unadorned chassis, and different robots will attach different parts to it, calling the appropriate "add" function when they do.

A ChassisBuilder simply creates a new Car every second and places it into the chassisQueue. A Director manages the build process by taking the next Car off the chassisQueue, putting it into the Cradle, telling all the robots to startWork( ), and suspending itself by calling waitUntilWorkFinished( ). When the work is done, the Director takes the Car out of the Cradle and puts in into the finishingQueue.

The Cradle is the crux of the signaling operations. A Mutex and a Condition object control both the working of the robots and indicate whether all the operations are finished. A particular type of robot can offer its services to the Cradle by calling the "offer" function appropriate to its type. At this point, that robot thread is suspended until the Director calls startWork( ), which changes the hiring flags and calls broadcast( ) to tell all the robots to show up for work. Although this system allows any number of robots to offer their services, each one of those robots has its thread suspended by doing so. You could imagine a more sophisticated system in which the robots register themselves with many different Cradles without being suspended by that registration process and then reside in a pool waiting for the first Cradle that needs a task completed.

After each robot finishes its task (changing the state of the Car in the process), it calls taskFinished( ), which sends a signal( ) to the readyCondition, which is what the Director is waiting on in waitUntilWorkFinished( ). Each time the director thread awakens, the state of the Car is checked, and if it still isn’t finished, that thread is suspended again.

When the Director inserts a Car into the Cradle, you can perform operations on that Car via the operator->( ). To prevent multiple extractions of the same car, a flag causes an error report to be generated. (Exceptions don’t propagate across threads in the ZThread library.)

In main( ), all the necessary objects are created and the tasks are initialized, with the ChassisBuilder begun last to start the process. (However, because of the behavior of the TQueue, it wouldn’t matter if it were started first.) Note that this program follows all the guidelines regarding object and task lifetime presented in this chapter, and so the shutdown process is safe.

Deadlock

Перейти на страницу:

Похожие книги

3ds Max 2008
3ds Max 2008

Одни уверены, что нет лучшего способа обучения 3ds Мах, чем прочитать хорошую книгу. Другие склоняются к тому, что эффективнее учиться у преподавателя, который показывает, что и как нужно делать. Данное издание объединяет оба подхода. Его цель – сделать освоение 3ds Мах 2008 максимально быстрым и результативным. Часто после изучения книги у читателя возникают вопросы, почему не получился тот или иной пример. Видеокурс – это гарантия, что такие вопросы не возникнут: ведь автор не только рассказывает, но и показывает, как нужно работать в 3ds Мах.В отличие от большинства интерактивных курсов, где работа в 3ds Мах иллюстрируется на кубиках-шариках, данный видеокурс полностью практический. Все приемы работы с инструментами 3ds Мах 2008 показаны на конкретных примерах, благодаря чему после просмотра курса читатель сможет самостоятельно выполнять даже сложные проекты.

Владимир Антонович Верстак , Владимир Верстак

Программирование, программы, базы данных / Программное обеспечение / Книги по IT