Чтение онлайн

на главную

Жанры

Системное программирование в среде Windows

Харт Джонсон М.

Шрифт:

0 <= nLost + nCons <= sequence

Об этом важном свойстве далее еще будет идти речь.

• О необходимости прекращения передачи поток производителя узнает лишь после проверки флага, устанавливаемого в блоке сообщения потока потребителя. Поскольку потоки не могут обмениваться между собой никакими сигналами, а вызов функции TerminateThread чреват нежелательными побочными эффектами, эта методика является простейшим способом остановки другого потока. Разумеется, чтобы эта методика была эффективной, работа потоков должна быть скоординированной. В то же время, подобное решение требует, чтобы поток не блокировался, иначе он не сможет тестировать флаг; способы решения проблемы блокированных

потоков обсуждаются в главе 10.

Объекты CRITICAL_SECTION предоставляют в наше распоряжение мощный механизм синхронизации, но, тем не менее, они не в состоянии обеспечить всю полноту необходимых функциональных возможностей. О невозможности отправки сигналов одним потоком другому уже говорилось, кроме того, эти объекты не позволяют воспользоваться конечными интервалами ожидания (time-out). Объекты синхронизации ядра Windows позволяют снизить остроту не только этих, но и других ограничений.

Мьютексы

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

Объекты мьютексов аналогичны объектам CS, однако, дополнительно к возможности их совместного использования различными процессами, они допускают конечные периоды ожидания, а мьютексы, покинутые (abandoned) завершающимся процессом, переходят в сигнальное состояние. [29] Поток приобретает права владения мьютексом (или блокирует (block) мьютекс) путем вызова функции ожидания (WaitForSingleObject или WaitForMultipleObjects) по отношению к дескриптору мьютекса и уступает эти права посредством вызова функции ReleaseMutex.

29

Выбирая необходимый тип объекта, руководствуйтесь следующим правилом: если упоминавшиеся ограничения приемлемы — используйте объекты CRITICAL_SECTION, если же имеется несколько процессов или требуются возможности мьютексов — применяйте мьютексы.

Как всегда, необходимо тщательно следить за тем, чтобы потоки своевременно освобождали ресурсы, в которых они больше не нуждаются. Поток может завладевать одним и тем же ресурсом несколько раз, и при этом не будет блокироваться даже в тех случаях, когда уже владеет данным ресурсом. В конечном счете, поток должен освободить мьютекс столько раз, сколько она его захватывала. Такая возможность рекурсивного захвата ресурсов, существующая и в случае объектов CS, может оказаться полезной для ограничения доступа к рекурсивным функциям, а также в приложениях, реализующих вложенные транзакции (nested transactions).

При работе с мьютексами мы будем пользоваться функциями CreateMutex, ReleaseMutex и OpenMutex.

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpsa, BOOL bInitialOwner, LPCTSTR lpMutexName)

BOOL ReleaseMutex(HANDLE hMutex)

bInitialOwner — если значение этого флага установлено равным True, вызывающий поток немедленно приобретает права владения новым мьютексом. Эта атомарная операция позволяет предотвратить приобретение прав владения мьютексом другими потоками, прежде чем это сделает поток, создающий мьютекс.

Как следует из самого его названия (initial owner — исходный владелец), этот флаг не оказывает никакого действия, если мьютекс уже существует.

lpMutexName — указатель на строку, содержащую имя мьютекса; в отличие от файлов имена мьютексов чувствительны к регистру. Если этот параметр равен NULL, то мьютекс создается без имени. События, мьютексы, семафоры, отображения файлов и другие объекты ядра, упоминаемые в данной книге, — все они используют одно и то же пространство имен, отличное от пространства имен файловой системы. Поэтому имена всех объектов синхронизации должны быть различными. Длина указанных имен не может превышать 260 символов.

Возвращаемое значение имеет тип HANDLE; значение NULL указывает на неудачное завершение функции.

Функция OpenMutex открывает существующий именованный мьютекс. Впоследствии эта функция не обсуждается, но используется в некоторых примерах. Эта функция дает возможность потокам, принадлежащим различным процессам, синхронизироваться так, как если бы они принадлежали одному и тому же процессу. Вызову функции OpenMutex в одном процессе должен предшествовать вызов функции CreateMutex в другом процессе. Для семафоров и событий, как и для отображенных файлов (глава 5), также имеются соответствующие функции Create и Open. При вызове этих функций всегда предполагается, что сначала один процесс, например сервер, вызывает функцию Create для создания именованного объекта, а затем другие процессы вызывают функцию Open, которая завершается неудачей, если именованный объект к этому моменту еще не был создан. Возможен и такой вариант, когда все процессы самостоятельно используют вызов функции Create с одним и тем же именем, если порядок создания объектов не имеет значения.

Функция ReleaseMutex освобождает мьютекс, которым владеет вызывающий поток. Если мьютекс не принадлежит потоку, функция завершается с ошибкой. 

BOOL ReleaseMutex(HANDLE hMutex)
 

Спецификация POSIX Pthreads поддерживает мьютексы. Имеются следующие основные функции:

• pthread_mutex_init

• pthread_mutex_destroy

• pthread_mutex_lock

• pthread_mutex_unlock

Функция pthread_mutex_lock является блокирующей и поэтому эквивалентна функции WaitForSingleObject в случае ее применения к дескриптору мьютекса. Функция pthread_mutex_trylock осуществляет опрос и не является блокирующей, соответствуя функции WaitForSingleObject в случае ее применения с нулевым значением интервала ожидания. Потоки Pthreads не поддерживают конечные интервалы ожидания и не предлагают средств, аналогичных Windows-объектам CRITICAL_SECTION.

Покинутые мьютексы

Мьютекс, владевший которым поток завершился, не освободив его, называют покинутым (abandoned), и его дескриптор переходит в сигнальное состояние. На то, что сигнализирующий дескриптор (дескрипторы) представляет покинутый мьютекс (мьютексы), указывает возврат функцией WaitForSingleObject значения WAIT_ABANDONED_0 или использование значения WAIT_ABANDONED_0 в качестве базового значения функцией WaitForMultipleObject.

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

Поделиться:
Популярные книги

Восход. Солнцев. Книга X

Скабер Артемий
10. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга X

Мастер 7

Чащин Валерий
7. Мастер
Фантастика:
фэнтези
боевая фантастика
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Мастер 7

Неудержимый. Книга XIV

Боярский Андрей
14. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIV

Все не случайно

Юнина Наталья
Любовные романы:
современные любовные романы
7.10
рейтинг книги
Все не случайно

Гром над Тверью

Машуков Тимур
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Гром над Тверью

Идущий в тени 5

Амврелий Марк
5. Идущий в тени
Фантастика:
фэнтези
рпг
5.50
рейтинг книги
Идущий в тени 5

Кровь, золото и помидоры

Распопов Дмитрий Викторович
4. Венецианский купец
Фантастика:
альтернативная история
5.40
рейтинг книги
Кровь, золото и помидоры

Неудержимый. Книга VIII

Боярский Андрей
8. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
6.00
рейтинг книги
Неудержимый. Книга VIII

Чужое наследие

Кораблев Родион
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Чужое наследие

Пистоль и шпага

Дроздов Анатолий Федорович
2. Штуцер и тесак
Фантастика:
альтернативная история
8.28
рейтинг книги
Пистоль и шпага

Мастер 4

Чащин Валерий
4. Мастер
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Мастер 4

Темный Патриарх Светлого Рода 6

Лисицин Евгений
6. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 6

Лорд Системы 14

Токсик Саша
14. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 14

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни