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

Вместе с тем переход от QNX 4 к QNX 6 вызвал изменения в реализации механизма обмена сообщениями и, как следствие, API-функций. Причиной этого стал переход от однопоточных к многопоточным процессам, при этом обмен сообщениями стал осуществляться не между процессами [43], а между потоками. Соответственно изменился и «адресат» сообщения. В QNX 4 в этом качестве выступал процесс и его можно было однозначно определить по его идентификатору — действительному (при работе на одном узле) или идентификатору виртуального канала («virtual circuit») при межузловых сообщениях. Таким образом, для того чтобы передать сообщение (функцией из семейства Send*()) в адрес некоего сервера, процессу-клиенту достаточно было «знать» этот идентификатор. Получал он его, как правило, либо от «родителя» искомого процесса, либо через сервис глобального пространства имен ( qnx_name_attach()и qnx_name_locate()).

Теперь же, в QNX 6, в качестве «адресата» сообщения стал выступать идентификатор соединения ( coid), и именно он требуется при вызове функций семейства MsgSend*(). Для создания же соединения с сервером клиенту необходимо «знать» триаду соединения: идентификатор этого процесса-сервера ( pid), дескриптор узла ( nd), на котором сервер выполняется, и идентификатор созданного сервером канала ( chid).

Вторым «возмущением», привнесенным QNX 6 в привычную и сложившуюся технику разработок, явился переход от идентификаторов узлов ( nid), которые являлись уникальными в пределах сети и однозначно определяли каждый узел, к дескрипторам узлов (nd), которые уникальны только в пределах каждого данного узла, но не в сети. Уникальность в пределах сети теперь должны обеспечивать символьные имена узлов.

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

<p>Организация обмена сообщениями на основе «семейных» процессов</p>

Рассмотрим, как можно организовать обмен сообщениями между потоками, принадлежащими процессам, связанным «родственными узами». Для простоты изложения, чтобы в дальнейшем не формулировать «поток, принадлежащий процессу», будем рассматривать однопоточные процессы и говорить (в традициях QNX 4) «обмен сообщениями между процессами».

Итак, пусть некий родительский процесспорождает на другом узле дочерний процесс. Под порождением будем подразумевать «запуск с узла», то есть запуск процесса, выполняемый утилитой onс опцией -f. Для порождения используем функцию spawn():

char* args[] = { "/net/904-3/home/ZZZ/bin/TestChild", NULL};

...

spawn("/home/ZZZ/bin/TestChild", 0, NULL, &InhProc, args, NULL);

Рассмотрим вначале проблемы, стоящие перед дочерним процессом при его желании связаться с родительским. Как уже указывалось, для создания соединения ему необходимо «знать» триаду соединения.

Пусть процессу-клиенту известно символьное имя узла, на котором функционирует искомый адресат. (При описываемой здесь «семейной» архитектуре разрабатываемой системы символьные имена обычно жестко определены и поэтому зачастую просто записываются в конфигурационном файле, откуда процессы всегда могут получить символьное имя нужного узла.) Для того чтобы получить дескриптор узла по известному имени, можно вызвать функцию netmgr_strtond(), которая преобразует имя узла в его дескриптор.

Однако вызов этой функции дочерним процессом приводит к неожиданному (по крайней мере, так было со мной...) на первый взгляд результату: функция возвращает дескриптор узла «с точки зрения» родительского процесса! Иными словами, нулевой дескриптор приписывается не узлу, на котором «живет» дочерний процесс, а узлу с родительским процессом. Другие дескрипторы тоже соотносятся с именами узлов так, как это выполняется на узле с родителем — порожденный процесс, унаследовав от родителя текущую рабочую и корневую директории, тем самым остался, если можно так выразиться, душой на своей исторической родине.

В [4] (глава Дмитрия Алексеева «Утилита on») этот вопрос был достаточно хорошо освещен и было сказано, что для решения проблемы следует перед порождением процесса вызвать функцию chroot()с именем узла, на котором процесс будет порожден (и при необходимости «обратным» вызовом chroot()с именем узла процесса-родителя после вызова spawn()). Это позволяет порожденному процессу обрести новую корневую директорию на том узле, где он выполняется. И тогда вызовы netmgr_strtond()будут возвращать дескрипторы узлов именно с точки зрения того узла, на котором функционирует порожденный процесс.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных