-->

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

На нашем литературном портале можно бесплатно читать книгу QNX/UNIX: Анатомия параллелизма, Цилюрик Олег Иванович-- . Жанр: Программирование / ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
QNX/UNIX: Анатомия параллелизма
Название: QNX/UNIX: Анатомия параллелизма
Дата добавления: 16 январь 2020
Количество просмотров: 315
Читать онлайн

QNX/UNIX: Анатомия параллелизма читать книгу онлайн

QNX/UNIX: Анатомия параллелизма - читать бесплатно онлайн , автор Цилюрик Олег Иванович

Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса. Некоторые из результатов испытаний тестовых примеров будут большим сюрпризом даже для самых бывалых программистов. Тем не менее излагаемые техники вполне доступны и начинающим программистам: для изучения материала требуется базовое знание языка программирования C/C++ и некоторое понимание «устройства» современных многозадачных ОС UNIX.

В качестве «испытательной площадки» для тестовых фрагментов выбрана ОСРВ QNX, что позволило с единой точки зрения взглянуть как на специфические механизмы микроядерной архитектуры QNX, так и на универсальные механизмы POSIX. В этом качестве книга может быть интересна и тем, кто не использует (и не планирует никогда использовать) ОС QNX: программистам в Linux, FreeBSD, NetBSD, Solaris и других традиционных ОС UNIX.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

1 ... 81 82 83 84 85 86 87 88 89 ... 106 ВПЕРЕД
Перейти на страницу:

 // устройством.

 static iofunc_attr_t attr;

 iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

 // здесь создается путевое имя для менеджера

 id = resmgr_attach(dpp, &resmgr_attr, "/dev/prior",

  _FTYPE_ANY, 0, &connect_funcs, &io_funcs, &attr);

 if (id == -1)

  perror("attach name"), exit(EXIT_FAILURE);

 ctp = dispatch_context_alloc(dpp);

 // старт менеджера как бесконечный цикл ожидания

 // поступающих сообщений для диспетчеризации:

 while (true) {

  if ((ctp = dispatch_block(ctp)) == NULL)

   perror("block error"), exit(EXIT_FAILURE);

  dispatch_handler(ctp);

 }

}

Здесь использован простейший однопоточный шаблон написания менеджера. Менеджер отрабатывает только одну команду

read()
(т.e. отрабатывает нестандартно; в целевом коде все остальные команды, например
open()
, он отрабатывает по умолчанию). По команде
read()
менеджер: а) возвращает в виде текстовой строки, завершающейся переводом строки, текущий приоритет (помните, что в QNX приоритеты «плавают»?), на котором он обрабатывает запрос, и б) делает это через один запрос, в оставшиеся разы создавая на всякий случай (почему «на всякий», сейчас станет понятно) ситуацию EOF (конца файла). Выполним несколько команд:

# prior &

# ls -l /dev/pr*

nrw-rw-rw- 1 root root 0 Dec 18 17:13 /dev/prior

Все соответствует нашим ожиданиям: менеджер ресурса запущен, он зарегистрировал в пространстве имен свое имя

/dev/prior
, по которому мы можем к нему обращаться. Теперь выполним обращения к нашему... «устройству». Для этого мы сознательно не станем пользоваться каким-либо специальным клиентом, запрашивающим наш созданный сервис, а воспользуемся самыми заурядными командами UNIX, которые ничего не подозревают о существовании нового сервиса:

# cat /dev/prior

10

# nice -n-5 cat /dev/prior

15

# nice -n-19 cat /dev/prior

29

Вот здесь и проявляется исключительная мощь техники написания менеджера ресурса: созданная минимальными средствами серверная служба «камуфлирует» специфичный QNX-механизм передачи сообщений микроядра под стандартные POSIX-запросы к файловой системе (

open()
,
read()
и т.д.), и стандартные команды UNIX «не видят» отличий новой серверной службы от стандартных файлов (устройств) UNIX. Вот для достижения такой полной совместимости с «привычками» команд UNIX и созданы «на всякий случай» те особенности формата, возвращаемого запросами
read()
, о которых упоминалось выше.

Теперь разработка, например драйвера некоторого специфичного устройства, перемещается из области шаманства «системного программиста» в область деятельности проблемного программиста, да и выполняется привычными высокоуровневыми инструментальными средствами, например С++.

Примечание

Пользуясь случаем, именно здесь уместно на примере созданного менеджера ресурсов продемонстрировать гибкость микроядерной архитектуры и техники менеджера ресурса, а заодно убедиться, что наследование приоритетов (критически важное свойство для систем реального времени) сохраняется при запросе к удаленному менеджеру ресурса, запущенному на другом узле сети (имя узла —

rtp
):

# on -frtp prior &

# ls -l /net/rtp/dev/pr*

nrw-rw--rw- 1 root root 0 Dec 18 17.09 /net/rtp/dev/prior

# nice -n-5 cat /net/rtp/dev/prior

15

# nice -n-19 cat /net/rtp/dev/prior

29

Многопоточный менеджер

Следующим шагом развития техники менеджера ресурсов является многопоточный менеджер. Фактически это объединение техники менеджера ресурсов с динамическим пулом потоков, рассмотренным выше.

Реальный работающий многопоточный менеджер с сопутствующим ему обстоятельным обсуждением приводился нами в книге [4] в главе «Драйверы». Мы не станем полностью приводить здесь этот достаточно объемный текст, поскольку он отличается от ранее показанного однопоточного менеджера только несколькими строками после вот этого оператора регистрации префикса имени менеджера:

// здесь создается путевое имя для менеджера

id = resmgr_attach(dpp, &resmgr_attr, "/dev/prior",

 _FTYPE_ANY, 0, &connect_funcs, &io_funcs, &attr);

if (id == -1)

 perror("attach name"), exit(EXIT_FAILURE);

Вот те несколько строк, которые, собственно, и превращают однопоточный менеджер в многопоточный:

...

thread_pool_attr_t pool_attr;

memset(&pool_attr, 0, sizeof pool_attr);

pool_attr.handle = dpp;

// это всегда остается так ...:

pool_attr.context_alloc = dispatch_context_alloc;

pool_attr.block_func = dispatch_block;

pool_attr.handler_func = dispatch_handler;

pool_attr.context_free = dispatch_context_free;

// численные параметры пула:

pool_attr.lo_water = 2;

pool_attr.hi_water = 6;

pool_attr.increment = 1;

pool_attr.maximum = 50;

thread_pool_t *tpp;

// флаг создания пула, который может принимать значения:

// POOL_FLAG_EXIT_SELF, POOL_FLAG_USE_SELF или,

1 ... 81 82 83 84 85 86 87 88 89 ... 106 ВПЕРЕД
Перейти на страницу:
Комментариев (0)
название