Читаем Системное программирование в среде Windows полностью

Первое, что нам предстоит сделать — это объединить два или более объекта синхронизации вместе с данными для создания сложного объекта синхронизации. Наиболее полезной комбинацией такого рода является модель переменных условий (condition variable model), включающая мьютекс и одно или несколько событий. Указанная модель играет весьма существенную роль в самых различных практических ситуациях, поскольку многие серьезные программные дефекты, обусловленные влиянием состязательности, проявляются именно тогда, когда объекты синхронизации Windows, особенно события, используются программистами неправильно. События имеют сложную природу и ведут себя по-разному в зависимости от того, какой именно из описанных в табл. 8.1 вариантов используется, и поэтому следует придерживаться определенных правил, устанавливаемых хорошо изученными моделями.

В последующих разделах показано, как систематизировать управление запуском и отменой выполнения каждого из совместно работающих потоков при помощи асинхронного вызова процедур (Asynchronous Procedure Calls, APC).

Другие проблемы производительности обсуждаются по мере необходимости.

<p>Модель переменных условий и свойства безопасности</p>

Многопоточные программы намного легче разрабатывать, делать их более понятными и сопровождать, если использовать известные, хорошо разработанные методики и модели. Эти вопросы уже обсуждались в главе 7, в которой для создания полезной концептуальной основы, позволяющей понять принципы работы многопоточных программ, были введены модель "хозяин/рабочий" ("boss/worker") и модель рабочей группы (work crew model). Понятие критических участков кода (critical sections) играет существенную роль при использовании мьютексов, а определение инвариантов (invariants) используемых структур данных также может принести немалую пользу. Наконец, даже для дефектов существуют свои модели, как это было показано на примере взаимной блокировки (deadlock) потоков.

Примечание

Компания Microsoft разработала собственный набор моделей, таких как апартаментная модель (apartment model) или модель свободных потоков (free threading). Эта терминология чаще всего встречается в технологии СОМ и кратко обсуждается в конце главы 11.

<p>Совместное использование событий и мьютексов</p>

Далее показано, как обеспечить совместное использование мьютексов и событий путем обобщения программы 8.2, представляющей описанную ниже ситуацию, с которой нам еще не раз предстоит столкнуться. Примечание. Это обсуждение в равной степени применимо как к мьютексам, так и к объектам CRITICAL_SECTION.

• Как мьютекс, так и событие связываются с блоком сообщений или иной структурой данных.

• Мьютекс определяет критический участок кода для доступа к объекту структуры данных.

• Событие используется для того, чтобы сигнализировать о появлении нового сообщения.

• Обобщая, можно утверждать, что мьютекс обеспечивает соблюдение условий, определяемых инвариантами объекта (то есть поддерживает свойства безопасности), а событие сигнализирует о том, что состояние объекта изменилось (например, сообщение было добавлено в буфер сообщений или удалено из него), и он мог перейти в известное состояние (например, в буфере сообщений присутствует, по крайней мере, одно сообщение).

• Один поток (в программе 8.2 — поток производителя) блокирует структуру данных, изменяет состояние объекта путем создания нового сообщения и применяет функции SetEvent или PulseEvent к событию, связанному с появлением нового сообщения.

• По крайней мере, один поток из числа остальных (в данном примере — поток потребителя) ожидает наступления события, сигнализирующего о том, что объект достиг требуемого состояния. Ожидание должно выполняться за пределами критического участка кода, чтобы поток производителя мог иметь доступ к объекту.

• Кроме того, поток потребителя может блокировать мьютекс, проверить состояние объекта (например, поступило ли в буфер новое сообщение) и отказаться от ожидания события, если объект уже находится в требуемом состоянии. 

<p>Модель переменных условий</p>

А теперь давайте объединим все это в едином фрагменте кода, представляющем то, что мы будем называть моделью переменных условий (condition variable model, CV model), которая может существовать в виде сигнальной (signal) и широковещательной (broadcast) моделей. В первых примерах будет использована широковещательная модель. Результат представляет собой программную модель, с которой мы будем работать еще не один раз, и которая может быть использована для решения широкого круга задач синхронизации. Для удобства изложения примеры сформулированы в терминах задачи производителя и потребителя.

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

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

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных
Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

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