Читаем 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.

Sleeping

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.

Priority

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.

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

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

3ds Max 2008
3ds Max 2008

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

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

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