QNX/UNIX: Анатомия параллелизма
QNX/UNIX: Анатомия параллелизма читать книгу онлайн
Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса. Некоторые из результатов испытаний тестовых примеров будут большим сюрпризом даже для самых бывалых программистов. Тем не менее излагаемые техники вполне доступны и начинающим программистам: для изучения материала требуется базовое знание языка программирования C/C++ и некоторое понимание «устройства» современных многозадачных ОС UNIX.
В качестве «испытательной площадки» для тестовых фрагментов выбрана ОСРВ QNX, что позволило с единой точки зрения взглянуть как на специфические механизмы микроядерной архитектуры QNX, так и на универсальные механизмы POSIX. В этом качестве книга может быть интересна и тем, кто не использует (и не планирует никогда использовать) ОС QNX: программистам в Linux, FreeBSD, NetBSD, Solaris и других традиционных ОС UNIX.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Теперь обратимся к технологии менеджера ресурсов. В этой технике менеджер регистрирует в пространстве имен (в файловой системе) уникальное имя, по которому клиенты, заинтересованные в его ресурсе, будут адресоваться к менеджеру. Идея не нова для мира UNIX (каталоги файловой системы
/proc
/dev
Техника менеджера ресурса вводит дополнительный уровень разрешения имен, который реализуется через менеджер процессов
procnto
int fd = open("/net/host/dev/srv", O_RDONLY);
по внутреннему содержанию в точности соответствует тому, что происходит в процессе организации обмена сообщениями при выполнении:
int coid = ConnectAttach(node, pid, chid, 0, 0);
и может даже при определенных обстоятельствах возвратить то же значение и уж по крайней мере всегда возвращает значение той же природы, хотя мы и говорим по привычке в первом случае «файловый дескриптор», а во втором - «идентификатор соединения». Здесь отчетливо видна подмена адресной триады
node
pid
chid
/net/host/dev/srv
Модель адресации менеджера ресурса в QNX, конечно, намного более универсальна, гибка и мобильна, нежели модель прямого обмена сообщениями. Например, можно написать сервер, который при запуске воспринимал бы полное имя, под которым он будет регистрироваться в пространстве имен, например (пусть даже некоторые варианты и сомнительны в своей осмысленности):
# server -n /dev/srv
# server -n /proc/srv
# server -n /fs/srv
Можно запустить несколько экземпляров такого сервера, возможно модифицированных использованием других ключей запуска:
# server -n /dev/srv1
# server -n /dev/srv2
Наконец, можно сделать это не только на своем локальном узле сети, но и на других сетевых узлах:
# on -f host1 server -n /dev/srv1
# on -f host1 server -n /dev/srv2
# on -f host2 server -n /dev/srv1
# on -f host2 server -n /dev/srv1
Теперь, если наш клиент выполнен так, что позволяет при запуске указать имя сервера, который он должен использовать, мы можем применить такой клиент для работы с самыми различными экземплярами серверов, где бы они ни находились в сети, например:
# client -s /dev/srv1
# client -s /net/host2/dev/srv1
Полный исходный код такой реализации будет показан в примере, к рассмотрению которого мы перейдем после завершения этого раздела.
В чем еще состоит различие, которое можно отнести к категории гибкости механизмов?
В краткой схеме, показанной кодом предыдущего раздела, вызовом:
MsgSend(coid, &bufou, sizeof(bufou), &bufin, sizeof(bufin));
может быть послано сообщение произвольной(в пределах абсолютных ограничений) длины (
sizeof(bufou)
MsgSend()
При обмене с менеджером ресурсов, в силу необходимости приведения клиентских запросов в «прокрустово ложе» POSIX, картина принципиально другая: каждый запрос может оперировать только с данными той длины, которая предопределена стандартом.
1. Команды группы
read()
2. Команды группы
write()
3. Команда
devctl()
write()
read()
devctl()
devctl()
4. Наконец, последним вариантом обмена с менеджером ресурса является обмен «сырыми», неформатированными сообщениями. Но это уже вариация простого обмена сообщениями, а как ее реализовать в коде, показано в приложении В. Зайцева.
С другой стороны, такая повышенная гибкость простого обмена сообщениями в отношении размеров передаваемых данных — предмет потенциальных ошибок, в то время как регламентируемое POSIX поведение обменных функций несет в себе дополнительный контроль корректности.
Эффективность реализации
Если техника менеджеров ресурсов — это только надстройка над базовым механизмом обмена сообщениями, то возникает совершенно естественный вопрос: какова же плата за использование этого производительного и «комфортного» механизма?
Для анализа «скоростных» характеристик альтернативных механизмов обмена сообщениями создадим группу приложений (клиентские и сервер, файлы cli.cc, clr.ccи srv.cc), а чтобы отдельно не выписывать определения, используемые приложениями, вынесем их в отдельный файл определений ( файл common.h).
const char VERSION[] = "vers. 1.03";
// имя, под которым будет регистрироваться в пространстве
// имен наш тестовый менеджер ресурса
static const char DEVNAME[_POSIX_PATH_MAX] = "/dev/srr";