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

So, while removing the guard on Count::value( ) seems to work, it’s not airtight, and thus on some machines you may see aberrant behavior.

<p>Terminating when blocked</p>

Entrance::run( ) in the previous example includes a call to sleep( ) in the main loop. We know that in that example the sleep will eventually wake up and the task will reach the top of the loop where it has an opportunity to break out of that loop by checking the isPaused( ) status. However, sleep( ) is just one situation in which a thread is blocked from executing, and sometimes you must terminate a task that’s blocked.

<p>Thread states</p>

A thread can be in any one of four states:

1.New: A thread remains in this state only momentarily, as it is being created. It allocates any necessary system resources and performs initialization. At this point it becomes eligible to receive CPU time. The scheduler will then transition this thread to the runnable or blocked state.

2.Runnable: This means that a thread can be run when the time-slicing mechanism has CPU cycles available for the thread. Thus, the thread might or might not be running at any moment, but there’s nothing to prevent it from being run if the scheduler can arrange it; it’s not dead or blocked.

3.Blocked: The thread could be run, but something prevents it. (It might be waiting for I/O to complete, for example.) While a thread is in the blocked state, the scheduler will simply skip it and not give it any CPU time. Until a thread reenters the runnable state, it won’t perform any operations.

4.Dead: A thread in the dead state is no longer schedulable and is not eligible to receive any CPU time. Its task is completed, and it is no longer runnable. The normal way for a thread to die is by returning from its run( ) function.

<p>Becoming blocked</p>

A thread is blocked when it cannot continue running. A thread can become blocked for the following reasons:

·         You’ve put the thread to sleep by calling sleep(milliseconds), in which case it will not be run for the specified time.

·         You’ve suspended the execution of the thread with wait( ). It will not become runnable again until the thread gets the signal( ) or broadcast( ) message. We’ll examine these in a later section.

·         The thread is waiting for some I/O to complete.

·         The thread is trying to enter a block of code that is guarded by a mutex, and that mutex has already been acquired by another thread.

The problem we need to look at now is this: sometimes you want to terminate a thread that is in a blocked state. It can be blocked for any of the reasons in the above list (except for IO, as you’ll see). If you can’t wait for it to get to a point in the code where it can check a state value and decide to terminate on its own, you have to abort the thread out of its blocked state.

<p>Interruption</p>

As you might imagine, it’s much messier to break out of the middle of a loop than it is to wait for the loop to get to a test of isCanceled( ) (or some other place where the programmer is ready to leave the loop). When you break out of a blocked task, you might be breaking out of your run( ) loop in a place where you must destroy objects and clean up resources. Because of this, breaking out of the middle of a run( ) loop in a task is more like throwing an exception than anything else, so in ZThreads, exceptions are used for this kind of abort. (This walks the fine edge of being an inappropriate use of exceptions because it means you are often using them for control flow.) To return to a known good state when terminating a task this way, carefully consider the execution paths of your code and properly clean up everything inside the catch clause. We’ll look at these issues in this section.

To terminate a blocked thread, the ZThread library provides the Thread::interrupt( ) function. This sets the interrupted status for that thread. A thread with its interrupted status set will throw an Interrupted_Exception if it is already blocked or it attempts a blocking operation. The interrupted status will be reset when the exception is thrown or if the task calls Thread::interrupted( ). As you’ll see, Thread::interrupted( ) provides a second way to leave your run( ) loop, without throwing an exception.

Here’s an example that shows the basics of interrupt( ):

//: C11:Interrupting.cpp

// Interrupting a blocked thread.

//{L} ZThread

#include "zthread/Thread.h"

#include

using namespace ZThread;

using namespace std;

class Blocked : public Runnable {

public:

  void run() {

    try {

      Thread::sleep(1000);

      cout << "Waiting for get() in run():";

      cin.get();

    } catch(Interrupted_Exception&) {

      cout << "Caught Interrupted_Exception" << endl;

      // Exit the task

    }

  }

};

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

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

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

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

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

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

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

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

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