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

In ZThreads, the basic class that uses a mutex and allows task suspension is the Condition, and you can suspend a task by calling wait( ) on a Condition. When external state changes take place that might mean that a task should continue processing, you notify the task by calling signal( ), to wake up one task, or broadcast( ), to wake up all tasks that have suspended themselves on that Condition object.

There are two forms of wait( ). The first takes an argument in milliseconds that has the same meaning as in sleep( ): "pause for this period of time." The difference is that in a timed wait( ):

1.       The Mutex that is controlled by the Condition object is released during the wait( ).

2.      You can come out of the wait( ) due to a signal( ) or a broadcast( ), as well as by letting the clock run out.

The second form of wait( ) takes no arguments; this version is more commonly used. It also releases the mutex, but this wait( ) suspends the thread indefinitely until that Condition object receives a signal( ) or broadcast( ).

Typically, you use wait( ) when you’re waiting for some condition to change that is under the control of forces outside the current function. (Often, this condition will be changed by another thread.) You don’t want to idly loop while testing the condition inside your thread; this is called a "busy wait," and it’s a bad use of CPU cycles. Thus, wait( ) allows you to suspend the thread while waiting for the world to change, and only when a signal( ) or broadcast( ) occurs (suggesting that something of interest may have happened), does the thread wake up and check for changes. Therefore, wait( ) provides a way to synchronize activities between threads.

Let’s look at a simple example. WaxOMatic.cpp applies wax to a Car and polishes it using two separate processes. The polishing process cannot do its job until the application process is finished, and the application process must wait until the polishing process is finished before it can put on another coat of wax. Both WaxOn and WaxOff use the Car object, which contains a Condition that it uses to suspend a thread inside waitForWaxing( ) or waitForBuffing( ):

//: C11:WaxOMatic.cpp

// Basic thread cooperation.

//{L} ZThread

#include "zthread/Thread.h"

#include "zthread/Mutex.h"

#include "zthread/Guard.h"

#include "zthread/Condition.h"

#include "zthread/ThreadedExecutor.h"

#include

#include

using namespace ZThread;

using namespace std;

class Car {

  Mutex lock;

  Condition condition;

  bool waxOn;

public:

  Car() : condition(lock), waxOn(false) {}

  void waxed() {

    Guard g(lock);

    waxOn = true; // Ready to buff

    condition.signal();

  }

  void buffed() {

    Guard g(lock);

    waxOn = false; // Ready for another coat of wax

    condition.signal();

  }

  void waitForWaxing() {

    Guard g(lock);

    while(waxOn == false)

      condition.wait();

  }

  void waitForBuffing() {

    Guard g(lock);

    while(waxOn == true)

      condition.wait();

  }

};

class WaxOn : public Runnable {

  CountedPtr car;

public:

  WaxOn(CountedPtr& c) : car(c) {}

  void run() {

    try {

      while(!Thread::interrupted()) {

        cout << "Wax On!" << endl;

        Thread::sleep(200);

        car->waxed();

        car->waitForBuffing();

      }

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

    cout << "Ending Wax On process" << endl;

  }

};

class WaxOff : public Runnable {

  CountedPtr car;

public:

  WaxOff(CountedPtr& c) : car(c) {}

  void run() {

    try {

      while(!Thread::interrupted()) {

        car->waitForWaxing();

        cout << "Wax Off!" << endl;

        Thread::sleep(200);

        car->buffed();

      }

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

    cout << "Ending Wax Off process" << endl;

  }

};

int main() {

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

  try {

    CountedPtr car(new Car);

    ThreadedExecutor executor;

    executor.execute(new WaxOff(car));

    executor.execute(new WaxOn(car));

    cin.get();

    executor.interrupt();

  } catch(Synchronization_Exception& e) {

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

  }

} ///:~

In Car’s constructor, a single Mutex is wrapped in a Condition object so that it can be used to manage inter-task communication. However, the Condition object contains no information about the state of your process, so you need to manage additional information to indicate process state. Here, Car has a single bool waxOn, which indicates the state of the waxing-polishing process.

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

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