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

To drive a Runnable object with a thread, you create a separate Thread object and hand a Runnable pointer to the Thread’s constructor. This performs the thread initialization and then calls the Runnable’s run( ) as an interruptible thread. By driving LiftOff with a Thread, the example below shows how any task can be run in the context of another thread:

//: C11:BasicThreads.cpp

// The most basic use of the Thread class.

//{L} ZThread

#include "LiftOff.h"

#include "zthread/Thread.h"

using namespace ZThread;

using namespace std;

int main() {

  try {

    Thread t(new LiftOff(10));

    cout << "Waiting for LiftOff" << endl;

  } catch(Synchronization_Exception& e) {

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

  }

} ///:~

Synchronization_Exception is part of the ZThread library and is the base class for all ZThread exceptions. It will be thrown if there is an error starting or using a thread.

A Thread constructor only needs a pointer to a Runnable object. It will perform the necessary initialization, call that Runnable’s run( ) member function to start the task, and then return to the calling thread, which in this case is the thread for main( ). In effect, you have made a member function call to LiftOff::run( ), and that function has not yet finished, but you can still perform other operations in the main( ) thread. (This ability is not restricted to the main( ) thread—any thread can start another thread.) You can see this by running the program. Even though LiftOff::run( ) has been called, the "Waiting for LiftOff" message will appear before the countdown has completed. Thus, the program is running two functions at once—LiftOff::run( ) and main( ).

You can easily add more threads to drive more tasks. Here, you can see how all the threads run in concert with one another:

//: C11:MoreBasicThreads.cpp

// Adding more threads.

//{L} ZThread

#include "LiftOff.h"

#include "zthread/Thread.h"

using namespace ZThread;

using namespace std;

int main() {

  const int sz = 5;

  try {

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

      Thread t(new LiftOff(10, i));

    cout << "Waiting for LiftOff" << endl;

  } catch(Synchronization_Exception& e) {

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

  }

} ///:~

The second argument for the LiftOff constructor identifies each task. When you run the program, you’ll see that the execution of the different tasks is mixed together as the threads are swapped in and out. This swapping is automatically controlled by the thread scheduler. If you have multiple processors on your machine, the thread scheduler will quietly distribute the threads among the processors.

The for loop can seem a little strange at first, because t is being created locally inside the for loop and then immediately goes out of scope and is therefore destroyed. This makes it appear that the thread itself might be immediately lost, but you can see from the output that the threads are indeed running to conclusion. When you create a Thread object, the associated thread is registered with the threading system, which keeps it alive. Even though the stack-based Thread object is lost, the thread itself lives on until its associated task completes. Although this may be counterintuitive from a C++ standpoint, the concept of threads is a departure from the norm: a thread creates a separate thread of execution that persists after the function call ends. This departure is reflected in the persistence of the underlying thread after the object vanishes.

<p>Creating responsive user interfaces</p>

As stated earlier, one of the motivations for using threading is to create a responsive user interface. Although we don’t cover graphical user interfaces in this book, you can still see a simple example of a console-based user interface.

The following example reads lines from a file and prints them to the console, sleeping (suspending the current thread) for a second after each line is displayed. (You’ll learn more about sleeping later in the chapter). During this process, the program doesn’t look for user input, so the UI is unresponsive:

//: C11:UnresponsiveUI.cpp

// Lack of threading produces an unresponsive UI.

//{L} ZThread

#include "zthread/Thread.h"

#include

#include

using namespace std;

using namespace ZThread;

int main() {

  const int sz = 100; // Buffer size;

  char buf[sz];

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

  ifstream file("UnresponsiveUI.cpp");

  while(file.getline(buf, sz)) {

    cout << buf << endl;

    Thread::sleep(1000); // Time in milliseconds

  }

  // Read input from the console

  cin.get();

  cout << "Shutting down..." << endl;

} ///:~

To make the program responsive, you can execute a task that displays the file in a separate thread. The main thread can then watch for user input so the program becomes responsive:

//: C11:ResponsiveUI.cpp

// Threading for a responsive user interface.

//{L} ZThread

#include "zthread/Thread.h"

#include

#include

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

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

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

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

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

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

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

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

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