Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / 3_управление процессами.doc
Скачиваний:
76
Добавлен:
20.06.2014
Размер:
1.59 Mб
Скачать

3.3.1.3. Организация многопоточной обработки запросов в модели "клиент-сервер"

Часто необходимо обрабатывать некоторые запросы на обслуживание. Традиционный подход заключается в том, что поток ждет сообщение, обрабатывает его, затем снова ждет и т.д. Другой подход заключается в создании нового потока всякий раз, когда приходит сообщение. Преимущества многопоточной обработки запросов иллюстрируются рис. 14.

Рис.14

3.3.2. Потоки и проблема глобальных переменных. Типы реализации потоков.

3.3.2.1. Потоки и проблема глобальных переменных

Многопоточные программы нужно изначально создавать как параллельные. Существующие программы, написанные как однопоточные, в общем случае используют глобальные (в пределах процесса) переменные.

Пример: пусть в UNIX-подобной системе процесс имеет два потока. Принято, что если системный запрос завершается неудачно, в глобальную переменнуюerrnoзаписывается код ошибки.

Поток 1 пытается получить доступ к чему-нибудь, осуществляя соответствующий запрос. ОС записывает результат в errno(например, "успешно"). Перед тем, как проверитьerrno, поток 1 прерывается. В это время поток 2 пытается получить доступ к чему-нибудь недоступному, осуществляя запрос,OCзаписывает вerrnoзначение "неуспешно". Перед тем, как проверитьerrno, поток 2 прерывается. Вновь получает управление поток 1, который проверяетerrnoс ошибочным для него результатом. Одно из решений проблемы – полностью запретить глобальные переменные. Можно отвести под глобальные переменные отдельный участок памяти и рассматривать их как дополнительные параметры процедур.

3.3.2.2. Пользовательские потоки

Пользовательские потокине являются потоками ядра, т.е. не диспетчеризуются. Переключение потоков на пользовательском уровне выполняется быстро, т.к. требует вызова ОС. Каждое приложение может выполнять собственную копию исполнительной библиотеки, следовательно, может выбирать требуемую стратегию планирования, а не следует единой встроенной стратегии диспетчера.

Проблемы:

– Трудно выполнять квантование потоков по времени (языковая библиотека, отвечающая за диспетчеризацию потоков, должна сообщать ядру о необходимости получать сигналы таймера. Передача их осуществляется с помощью т.н. обратного вызова или вызова вверх – upcall). Когда происходит прерывание от таймера, управление передаётся заданной подпрограмме из исполнительной библиотеки текущего приложения, которая решает, какой из потоков приложения исчерпал свой квант времени.

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

– Проблему представляют также параллельные вызовы самой языковой библиотеки несколькими потоками.

– В случае возникновения ошибки ОС может вернуть управление общей для всех подпрограмме обработки исключений.

– Не может быть задействовано несколько процессоров, т.к. ОС "видит" один процесс.

3.3.2.3. Потоки ядра

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

Основной недостаток – ресурсные затраты на переключение контекста, которые примерно в 10 раз превышают затраты на переключение пользовательских потоков. Все переключение потоков выполняется через ядро. Библиотеки для ОС, поддерживающих потоки ядра, обычно реентерабельны, это позволяет избежать проблемм, связанных с управлением пользовательскими потоками. Примерами ОС, поддерживающих потоки ядра, являются Windows2000,Mach,ChorusиOS/2.