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

      if(--countDown == 0) return;

      Thread::yield();

    }

  }

};

int main() {

  try {

    ThreadedExecutor executor;

    for(int i = 0; i < 5; i++)

      executor.execute(new YieldingTask(i));

  } catch(Synchronization_Exception& e) {

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

  }

} ///:~

You can see that the task’s run( ) member function consists entirely of an infinite loop. By using yield( ), the output is evened up quite a bit over that without yielding. Try commenting out the call to Thread::yield( ) to see the difference. In general, however, yield( ) is useful only in rare situations, and you can’t rely on it to do any serious tuning of your application.

<p>Sleeping</p>

Another way you can control the behavior of your threads is by calling sleep( ) to cease execution of that thread for a given number of milliseconds. In the preceding example, if you replace the call to yield( ) with a call to sleep( ), you get the following:

//: C11:SleepingTask.cpp

// Calling sleep() to pause for awhile.

//{L} ZThread

#include

#include "zthread/Thread.h"

#include "zthread/ThreadedExecutor.h"

using namespace ZThread;

using namespace std;

class SleepingTask : public Runnable {

  int countDown;

  int id;

public:

  SleepingTask(int ident = 0) : countDown(5), id(ident) {}

  ~SleepingTask() {

    cout << id << " completed" << endl;

  }

  friend ostream&

  operator<<(ostream& os, const SleepingTask& st) {

    return os << "#" << st.id << ": " << st.countDown;

  }

  void run() {

    while(true) {

      try {

        cout << *this << endl;

        if(--countDown == 0) return;

        Thread::sleep(100);

      } catch(Interrupted_Exception& e) {

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

      }

    }

  }

};

int main() {

  try {

    ThreadedExecutor executor;

    for(int i = 0; i < 5; i++)

      executor.execute(new SleepingTask(i));

  } catch(Synchronization_Exception& e) {

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

  }

} ///:~

Thread::sleep( ) can throw an Interrupted_Exception (you’ll learn about interrupts later), and you can see that this is caught in run( ). But the task is created and executed inside a try block in main( ) that catches Synchronization_Exception (the base class for all ZThread exceptions), so wouldn’t it be possible to just ignore the exception in run( ) and assume that it will propagate to the handler in main( )? This won’t work because exceptions won’t propagate across threads back to main( ). Thus, you must handle any exceptions locally that may arise within a task.

You’ll notice that the threads tend to run in any order, which means that sleep( ) is also not a way for you to control the order of thread execution. It just stops the execution of the thread for awhile. The only guarantee that you have is that the thread will sleep at least 100 milliseconds (in this example), but it may take longer before the thread resumes execution, because the thread scheduler still has to get back to it after the sleep interval expires.

If you must control the order of execution of threads, your best bet is to use synchronization controls (described later) or, in some cases, not to use threads at all, but instead to write your own cooperative routines that hand control to each other in a specified order.

<p>Priority</p>

The priority of a thread tells the scheduler how important this thread is. Although the order that the CPU runs a set of threads is indeterminate, the scheduler will lean toward running the waiting thread with the highest priority first. However, this doesn’t mean that threads with lower priority aren’t run (that is, you can’t get deadlocked because of priorities). Lower priority threads just tend to run less often.

Here’s MoreBasicThreads.cpp modified so that the priority levels are demonstrated. The priorities are adjusting by using Thread’s setPriority( ) function.

//: C11:SimplePriorities.cpp

// Shows the use of thread priorities.

//{L} ZThread

#include "zthread/Thread.h"

#include

#include

using namespace ZThread;

using namespace std;

class SimplePriorities : public Runnable {

  int countDown;

  volatile double d; // No optimization

  int id;

public:

  SimplePriorities(int ident = 0): countDown(5),id(ident){}

  ~SimplePriorities() throw() {

    cout << id << " completed" << endl;

  }

  friend ostream&

  operator<<(ostream& os, const SimplePriorities& sp) {

    return os << "#" << sp.id << " priority: "

      << Thread().getPriority()

      << " count: "<< sp.countDown;

  }

  void run() {

    while(true) {

      // An expensive, interruptable operation:

      for(int i = 1; i < 100000; i++)

        d = d + (M_PI + M_E) / (double)i;

      cout << *this << endl;

      if(--countDown == 0) return;

    }

  }

};

int main() {

  try {

    Thread high(new SimplePriorities);

    high.setPriority(High);

    for(int i = 0; i < 5; i++) {

      Thread low(new SimplePriorities(i));

      low.setPriority(Low);

    }

  } catch(Synchronization_Exception& e) {

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

  }

} ///:~

Here, operator<<( ) is overridden to display the identifier, priority, and countDown value of the task.

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

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

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

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

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

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

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

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

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