Практикум по курсу "Системное программное обеспечение": Учебное пособие (Программа курса, методические указания к изучению дисциплины, содержание и методические рекомендации к выполнению контрольной работы), страница 9

ReleaseDC – освобождение объекта в памяти, соответствующего доступному для рисования контексту устройства. Окно не уничтожает, и ничего на нем не стирает.

Исключающий семафор.

Системный вызов CreateMutex создает взаимоисключающий (бинарный) анонимный семафор и возвращает его дескриптор. Хотя, как правило, семафор создается для управления доступом к некоторому ресурсу, при создании семафора этот ресурс указывать не надо. И вообще, само наличие семафора никак не ограничивает выполнение потоков создавшего его приложения. В этом можно убедиться на примере программы Threads:  отключение режима взаимного исключении (mutex) при помощи меню не требует уничтожения объекта семафора, а только меняет значение переменной bUseMutex, не имеющей прямой связи с этим объектом. Для того, чтобы созданный семафор реально обеспечил режим взаимного исключения, в функциях, выполняемых конкурирующими потоками, все участки кода, требующие исключительного доступа к некотором ресурсу, должны выполняться между вызовами WaitForSingleObject и ReleaseMutex, принимающими дескриптор данного семафора в качестве параметра. Первый вызов блокирует текущий поток в ожидании, когда семафор будет свободен, после чего захватывает его. Второй вызов освобождает семафор. Реализация семафора гарантирует, что он не может быть захвачен одновременно двумя потоками.

В программе Threads все рабочие потоки выполняют один и тот же код, поэтому пара WaitForSingleObject и ReleaseMutex тоже одна, и она окружает вызов функции DrawProc. При выключенном режиме взаимного исключения (ложном значении bUseMutex) функция DrawProc выполняется одна, без такого окружения, то есть каждый поток приступает в отрисовке очередной порции прямоугольников не дожидаясь, пока другой поток завершит выполнение DrawProc.

Настоящей необходимости во взаимном исключении в этом примере нет, так как каждый поток рисует в своем собственном дочернем окне. При включенном режиме взаимного исключения в данном приложении можно говорить, с равной степенью достоверности, об исключительном доступе дочерних потоков к центральному процессору, экрану или к функции DrawProc.

Окно-список

Окно-список создается при помощи системного вызова CreateWindow, с указанием первым параметром стандартного класса "LISTBOX". В данном приложении используются следующие стандартные операции с окном-списком:

ListBox_AddString – добавление строки;

ListBox_SetCurSel – установка выделения на строке с указанным номером;

ListBox_GetCurSel – получение номера выделенной строки;

ListBox_ResetContent – очистка списка.

Форматированный вывод текста.

Единый формат вывода текста используется библиотечными функциями языка С, такими, как printf для стандартного вывода (консоли или канала), fprintf для файла, sprint для строки. Вариант с ‘w’  в начале имени функции означает работу с расширенными символами в системе Unicode. Эти функции позволяют комбинировать константные строки со значениями переменных различных типов и специальными символами, такими, как перенос строки или табуляция, а также гибко управлять форматом вывода числовых данных.

Пример выполнения задания

Для примера рассмотрим решение заданий контрольной работы для варианта 10.

Задание 1.

Вопрос: Насколько быстро реагирует программа на включение-выключение режима взаимного исключения?

Ответ: Переключение режима происходит не сразу. При включении режима взаимного исключения в течении нескольких секунд потоки продолжают случайное чередование активности. Постепенно все потоки, кроме какого-то одного входят в состояние длительного покоя, значения количеств прямоугольников для этих потоков становится «круглым». Далее рисуют по очереди. При выключении режима взаимного исключения потоки включаются в режим случайного перемежения активности не раньше, чем дождутся своей очереди на mutex, то есть по одному, в случайном порядке, в течение довольно длительного времени.

Задание 2.