Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответ - Екзаменаційні питання з курсу ОС.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

Содержание

  [убрать] 

  • 1 Общие сведения

  • 2 Версии

  • 3 См. также

  • 4 Ссылки

  • 5 Литература

Общие сведения[править | править вики-текст]

Windows API спроектирован для использования в языке Си для написания прикладных программ, предназначенных для работы под управлением операционной системы MS Windows. Работа через Windows API — это наиболее близкий к операционной системе способ взаимодействия с ней из прикладных программ. Более низкий уровень доступа, необходимый только для драйверов устройств, в текущих версиях Windows предоставляется черезWindows Driver Model.

Windows API представляет собой множество функций, структур данных и числовых констант, следующих соглашениям языка Си. Все языки программирования, способные вызывать такие функции и оперировать такими типами данных в программах, исполняемых в среде Windows, могут пользоваться этим API. В частности, это языки C++, Pascal, Visual Basic и многие другие.

Для облегчения программирования под Windows, в компании Microsoft и сторонними разработчиками было предпринято множество попыток создать библиотеки и среды программирования, частично или полностью скрывающие от программиста особенности Windows API, и предоставляющие ту или иную часть его возможностей в более удобном виде. В частности, сама Microsoft в разное время предлагала библиотеки Active Template Library(ATL)/Windows Template Library (WTL), Microsoft Foundation Classes (MFC), .Net/WinForms/WPF. Компания Borland (ныне Embarcadero, её преемник в части средств разработки) предлагала OWL и VCL. Есть кросс-платформенные библиотеки, такие как Qt, Tk и многие другие. Весомая часть этих библиотек сконцентрирована на облегчении программирования графического интерфейса пользователя.

Для облегчения переноса на другие платформы программ, написанных с опорой на Windows API, сделана библиотека Wine.

14. Призначення функцій WaitForSingleObject та WaitForMultipleObjects.

Секреты многопоточности: изучаем модульное тестирование в сфере мобильного программинга

Очень часто в наших статьях мы упоминали о тех или иных особенностях языка C++, касающихся написания многопоточных приложений. C++ не имеет нативной поддержки работы со множеством тредов, и поэтому программисту приходится самому заботиться о правильном поведении и безопасности своего кода. Для этих целей Windows предоставляет множество средств, о которых мы сегодня поговорим.

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

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

Для большей наглядности можно рассмотреть следующий код:

Ожидаем завершение потока

// Запускаем поток HANDLE hWorkerThread = ::CreateThread( ... ); // Перед окончанием работы надо каким-либо образом сообщить рабочему потоку, что пора закачивать ... // Ждем завершения потока DWORD dwWaitResult = ::WaitForSingleObject( hWorkerThread, INFINITE ); if( dwWaitResult != WAIT_OBJECT_0 ) { // обработка ошибки } // Хэндл потока можно закрыть ::CloseHandle( hWorkerThread );

В этом примере мы создаем поток с помощью функции CreateThread, а затем, перед завершением программы, ожидаем, когда наш поток отработает, чтобы закрыть его описатель. Собственно, вся магия заключается тут в API-функции WaitForSingleObject. Но об этом чуть ниже.

WaitForSingleObject и WaitForMultipleObjects

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

Сколько времени ждать наступления сигнального состояния, API решает на основе второго параметра — времени в миллисекундах. В случае его истечения функция вернет WAIT_TIMEOUT. Ожидать изменения состояния объекта можно бесконечно, для этого нужно передать во втором параметре значение INFINITE. Или же можно вообще не приостанавливать поток, а просто проверить состояния кернел обжекта, сделав интервал ожидания равным нулю. Когда объект переходит в сигнальное состояние, функция завершается, возвращая значение WAIT_OBJECT_0.

Но из названия WaitForSingleObject должно быть понятно, что это всего лишь частный случай API-функции WaitForMultipleObjects, которая предоставляет гораздо больше возможностей. Давай взглянем на ее прототип.

Описание WaitForMultipleObjects

DWORD WINAPI WaitForMultipleObjects( __in DWORD nCount, __in const HANDLE *lpHandles, __in BOOL bWaitAll, __in DWORD dwMilliseconds );

Основное отличие этой API-функции от WaitForSingleObject в том, что она может ожидать изменения состояния сразу нескольких объектов.

Описатели этих объектов передаются в массиве в параметре const HANDLE *lpHandles. Количество элементов массива задается с помощью DWORD nCount, а BOOL bWaitAll позволяет приостанавливать поток до тех пор, пока все объекты ядра не перейдут в сигнальное состояние.

Возвращаемые значения практически идентичны значениям WaitForSingleObject, с той лишь разницей, что если bWaitAll == FALSE, то в случае установки одного из объектов в сигнальное состояние мы получаем на выходе WAIT_OBJECT_0 + object_index_in_array. То есть, если из результата вычесть WAIT_OBJECT_0, то мы узнаем индекс объекта в массиве, который перешел в сигнальное состояние. Теперь, когда мы поняли, как работают функции WaitFor***, можно подробнее рассмотреть, чем же таким являются объекты ядра.

WaitForMultipleObjects и иже с ней могут мониторить объекты событий (Events), мьютексы, семафоры, процессы, потоки, таймеры ожидания, консольный ввод и некоторые другие виды объектов. Мьютексы, события и семафоры служат специально для целей синхронизации, поэтому на них стоит остановиться подробнее.