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

на главную

Жанры

QNX/UNIX: Анатомия параллелизма
Шрифт:

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

Примечание

Например, в принципиально однозадачной операционной системе MS-DOS исторически первой службой, требующей параллельного выполнения, была подсистема спулинга печати. Но добавлять ее в систему пришлось «по живому», поскольку основная структура системы уже сложилась и стабилизировалась (к версии 2.x), а механизмы параллелизма в этой структуре были изначально отвергнуты на корню. И с этого времени начинается затянувшаяся на многие годы история развития уродливой надстройки над MS-DOS — технологии создания TSR-приложений (terminate and stay resident), программного мультиплексора INT 2F

и других.

Новое «пришествие» механизмов параллельного выполнения (собственно, уже хорошо проработанных к этому времени в отрасли мэйнфреймов) начинается с появлением многозадачных ОС, разделяющих по времени выполнение нескольких задач. Для формализации (и стандартизации поведения) развивающихся параллельно программных ветвей создаются абстракции процессов, а позже и потоков. Простейший случай параллелизма — когда N (N>1) задач разделяют между собой ресурсы: время единого процессора, общий объем физической оперативной памяти…

Но многозадачное разделение времени — не единственный случай практической реализации параллельных вычислений. В общем случае программа может выполняться в аппаратной архитектуре, содержащей более одного (M) процессора (SMP-системы). При этом возможны принципиально отличающиеся по поведению ситуации:

• Количество параллельных ветвей (процессов, потоков) N больше числа процессоров M, при этом некоторые вычислительные ветви находятся в блокированных состояниях, конкурируя с выполняющимися ветвями за процессорное время. (Частный случай — наиболее часто имеющее место выполнение N ветвей на одном процессоре.)

• Количество параллельных ветвей (процессов, потоков) N меньше числа процессоров M, при этом все ветви вычисления могут развиваться действительно параллельно, а блокированные состояния возникают только при необходимости синхронизации и обмена данными между параллельными ветвями.

Все механизмы параллелизма проектируются (и это находит прямое отражение в POSIX-стандартах, а еще более в текстах комментариев к стандартам) и должны использоваться так, чтобы неявно не допускались какие-либо предположения об относительных скоростях параллельных ветвей и моментах достижения ими (относительно друг друга) конкретных точек выполнения. [4] Так, в программном фрагменте:

4

Это положение напрямую диктуется определением «слабосвязанных процессов», впервые сформулированным Э. Дейкстрой [10]. Заметим, что фундаментальная и стройная «картина мира», выстроенная Э. Дейкстрой и считающаяся классикой, исчерпывающе («необходимо и достаточно») описывает систему процессов равного приоритета. Расширение реальных систем атрибутом приоритета затуманивает прозрачность этой модели и делает все гораздо сложнее…

void* threadfunc(void* data) {

// оператор 1:

}

...

pthread_create(NULL, NULL, threadfunc, NULL);

// оператор 2:

...

нельзя допускать никаких априорных предположений о том, как пойдет дальнейшее выполнение после точки ветвления (точки вызова

pthread_create
): а) будет выполняться «оператор 2» в родительском потоке; б) будет выполняться «оператор 1» в порожденном потоке; в) на различных процессорах будут действительно одновременно выполняться «оператор 1» и «оператор 2»… Программный код должен быть организован так, чтобы в любых аппаратных конфигурациях (количество процессоров, их скорости, особенности кэширования памяти процессорами и другие характеристики) результаты выполнения были полностью эквивалентны.

Благодаря наличию в составе ОС QNX сетевой подсистемы QNET, органично обеспечивающей «прозрачную» интеграцию сетевых узлов в единую многомашинную систему, возникает дополнительный источник параллелизма (а вместе с тем и дополнительных хлопот), еще более усложняющий общую картину: запросы по QNET к сервисам, работающим на одном сетевом узле, со стороны клиентских приложений, работающих на других. Например, ежедневно выполняя простейшую команду:

# cp /net/host/dev/ser1 ./file

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

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

Приведенная выше аргументация — это далеко не полный перечень причин, по которым стоит еще пристальнее и с большей заинтересованностью взглянуть на техники параллельной организации вычислительного процесса. В литературе неоднократно отмечалось (например, [11]), что даже в тех случаях, когда приложение заведомо никогда и нигде не будет использоваться на многопроцессорной платформе, более того, когда логика приложения не предполагает естественного параллелизма как «одновременности выполнения», — даже тогда расщепление крупного приложения на логические фрагменты, которые построены как параллельные участки кода, взаимодействующие в ограниченном числе точек контакта, — это путь построения «прозрачного» для написания и понятного для сопровождения программного кода. И как следствие, этот путь (иногда на первый взгляд кажущийся несколько искусственным и привнесенным) — путь построения приложений высокой надежности, свободных от ошибок, характерных для громоздких монолитных приложений, и простых в своем последующем развитии и сопровождении.

Как уже неоднократно отмечалось, параллельная техника выражения в программном коде, пусть даже принципиально последовательных процессов, сопряжена с определенными трудностями: необходимость отличного, «параллельного», взгляда на описываемые процессы и отсутствие привычки применять специфические разделы API, редко используемые в классическом «последовательном» программировании. Единожды освоив эту технику, применять ее в дальнейшем становится легко и просто. Возможно и большее число рутинных приемов использования параллельной техники — в своей книге мы постарались «рассыпать» по тексту множество программных иллюстраций.

Наконец, есть еще одна, последняя особенность предлагаемого вашему вниманию материала: значительная часть приводимых здесь примеров и описаний относится ко всему многообразию ОС, поддерживающих POSIX-стандарт, однако акцент делается на не совсем очевидные особенности построения так называемых «приложений реального времени» [4]. В первую очередь это касается принципов синхронизации задач, совместно использующих общий ресурс. К сожалению, приемы программирования, широко распространенные при параллельном выполнении задач общего назначения, могут привести к не совсем предсказуемым результатам (по времени реакции) при построении систем реального времени. Особенности построения параллельно исполняемых систем в сферах реального времени и стали тем ключевым моментом, ориентируясь на который мы строили этот текст.

Семейства API

Общее множество вызовов API (Application Program Interface — интегральное наименование всего множества вызовов из программной среды к услугам операционной системы), реализуемое операционной системой (ОС) реального времени QNX, естественным образом разделяется на три независимых подгруппы:

• Native QNX API — это самодостаточный набор вызовов, развиваемый со времен ранних версий QNX (когда вопрос о совместимости с POSIX еще не стоял); является естественным базисом этой системы, отображающим «микроядерность» ее архитектуры, но по соображениям возможной совместимости и переносимости он является также и исключительной принадлежностью этой ОС.

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

Энфис 5

Кронос Александр
5. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 5

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

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

Я еще не князь. Книга XIV

Дрейк Сириус
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще не князь. Книга XIV

Последний попаданец

Зубов Константин
1. Последний попаданец
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Последний попаданец

Эволюция мага

Лисина Александра
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эволюция мага

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Третий. Том 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 3

Аватар

Жгулёв Пётр Николаевич
6. Real-Rpg
Фантастика:
боевая фантастика
5.33
рейтинг книги
Аватар

Предатель. Ты не знаешь о сыне

Безрукова Елена
3. Я тебя присвою
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Предатель. Ты не знаешь о сыне

(не)Бальмануг. Дочь 2

Лашина Полина
8. Мир Десяти
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
(не)Бальмануг. Дочь 2

Ученик

Губарев Алексей
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Ученик

Ледяное проклятье

Михайлов Дем Алексеевич
4. Изгой
Фантастика:
фэнтези
9.20
рейтинг книги
Ледяное проклятье

Снегурка для опера Морозова

Бигси Анна
4. Опасная работа
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Снегурка для опера Морозова

Сумеречный стрелок

Карелин Сергей Витальевич
1. Сумеречный стрелок
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок