Олег Цилюрик - QNX/UNIX: Анатомия параллелизма

Тут можно читать онлайн Олег Цилюрик - QNX/UNIX: Анатомия параллелизма - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Символ-Плюс, год 2006. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    QNX/UNIX: Анатомия параллелизма
  • Автор:
  • Жанр:
  • Издательство:
    Символ-Плюс
  • Год:
    2006
  • Город:
    Санкт-Петербург
  • ISBN:
    5-93286-088-Х
  • Рейтинг:
    4.56/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 100
    • 1
    • 2
    • 3
    • 4
    • 5

Олег Цилюрик - QNX/UNIX: Анатомия параллелизма краткое содержание

QNX/UNIX: Анатомия параллелизма - описание и краткое содержание, автор Олег Цилюрик, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

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

QNX/UNIX: Анатомия параллелизма - читать онлайн бесплатно ознакомительный отрывок

QNX/UNIX: Анатомия параллелизма - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Олег Цилюрик
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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

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

Теперь обсудим проблемы, стоящие перед родительским процессом. Если мы хотим отсылать сообщения с родительского процесса на порожденный, то два из трех членов триады родительский процесс может легко получить: дескриптор узла — с помощью функции netmgr_strtond(), а идентификатор порожденного процесса возвращается функцией spawn(). Но вот с дескриптором канала опять появляется риск «не угадать». Кроме того, если родитель породит дочерний процесс и немедленно после этого попытается подсоединиться к каналу, который должен создать этот процесс, то, вероятнее всего, функция ConnectAttach()вернет -1, поскольку порожденный процесс еще не успеет к тому времени создать канал. Значит, понадобится цикл на N попыток с паузой в ожидании открытия.

Не проще ли тогда просто выполнить синхронизацию? То есть родительскому процессу дождаться сообщения от дочернего процесса, которое будет означать, что порожденный процесс выполнил все необходимые действия по своему развертыванию и в частности создал канал. И теперь совершенно естественно передать в этом синхронизирующем сообщении дескриптор созданного канала. После принятия сообщения родительский процесс имеет все необходимые ему данные для выполнения функции отсылки сообщения MsgSend().

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

Ниже приводится образец кода, реализующего этот подход. Обратите внимание на значение аргумента index, задаваемое в вызовах функции ConnectAttach()равным _NTO_SIDE_CHANNEL. В примерах из [1], книги, безусловно, основополагающей для любого программиста под QNX 6, для упрощения изложения это значение устанавливается в 0. Однако значение, равное _NTO_SIDE_CHANNEL, гарантирует, что возвращаемое функцией значение идентификатора соединения будет взято не из того же пространства, из которого выделяются файловые дескрипторы; в противном случае возникают проблемы, достаточно определенно обрисованные в описании функции ConnectAttach(), приведенном в технической документации QNX.

Пример кода родительского процесса

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char **argv) {

int nid; // Дескриптор удаленного узла

int PChanid; // Идентификатор созданного канала

int CChanid; // Идентификатор канала, созданного

// порожденным процессом на удаленном узле

int coid; // Идентификатор связи с порожденным

// процессом по созданному им каналу

int rcvid; // Идентификатор отправителя полученного

// сообщения int

ErrCode; // Код ошибки

char *args[] = {

"/net/904-3/home/ZZZ/BIN/TestChild",

"pid данного процесса",

"идентификатор канала",

NULL

};

char BufName[100], Bufpid[12],

Bufchanid[12], RecBuffer[100];

char SendBuf[100] = "привет, сынок!";

pid_t procid, childid;

struct inheritance Inhproc;

setlocale(LC_CTYPE, "C-TRADITIONAL");

if ((PChanid = ChannelCreate(0)) == -1)

printf("Родитель: странно, но не удалось "

"создать канал\n");

else printf("Родитель: канал PChanid = %i создан\n", PChanid);

strcpy(BufName, "Bed-Test");

// Передаем порожденному процессу свой pid...

args[1] = itoa(procid = getpid(), Bufpid, 10);

// ... и дескриптор канала

args[2] = itoa(PChanid, Bufchanid, 10);

InhProc flags = SPAWN_SETND | SPAWN_NOZOMBIE;

if ((nid = netmgr_strtond(BufName, NULL)) == -1) {

printf("Родитель, отсутствует %s\n", BufName);

return(-1);

} else printf("Родитель: найден узел %s, его nid = %i\n", BufName, nid);

InhProc nd = nid;

sprintf(BufName, "/net/Bed-Test/");

chroot(BufName);

errno = 0;

childid = spawn(args[0], 0, NULL, &InhProc, args, NULL);

ErrCode = errno;

sprintf(BufName, "/net/904-3/");

chroot(BufName);

if (childid- = -1)

printf("Родитель: не удалось породить процесс,"

" errno = %i\n", ErrCode);

else

printf("Родитель, мой id = %i,"

"порожденный процесс имеет id = %i\n", procid, childid);

if ((rcvid = MsgReceive(PChanid, RecBuffer, 100, NULL)) == -1)

printf("Родитель: от дитятки не удалось"

" получить сообщение\n");

else {

printf("Родитель: от дитятки получено"

" сообщение:\"%s\"\n", RecBuffer);

CChanid = atoi(RecBuffer);

strcpy(RecBuffer, "спасибо, сынок");

if (MsgReply(rcvid, EOK, RecBuffer, 100) == -1)

printf("Родитель: почему-то не удалось "

"ответить сыночку: Ау, где ты?\n");

}

if ((coid =

ConnectAttach(nid, childid, CChanid, _NTO_SIDE_CHANNEL, 0)) == -1) {

printf("Родитель: странно, но не смог установить"

" канал связи с ребенком:"

"nid = %i childid = %i CChanid = %i\n", nid, childid, CChanid);

return(-1);

}

printf("Родитель: установил связь coid = %i с"

" ребенком\n", coid);

errno = 0;

if (MsgSend(coid, SendBuf, 100, SendBuf, 100) == -1)

printf("Родитель: на MsgSend получил errno = %i\n", errno);

else

printf("Родитель, получен отклик на MsgSend()"

", \"%s\"\n", SendBuf);

printf("Родитель: позвольте откланяться\n");

ChannelDestroy(Pchanid);

ConnectDetach(CChanid);

return(0);

}

Пример кода порожденного процесса

#include

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char **argv) {

int nid; // Дескриптор текущего узла

int CChanid; // Идентификатор созданного канала

int coid; // Идентификатор связи с родителем

// по созданному им каналу

pid_t Parpid; // Идентификатор родительского процесса

int rcvid; // Идентификатор отправителя

// полученного сообщения

char BufName[100];

char SendBuf[100], RecBuf[100];

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Олег Цилюрик читать все книги автора по порядку

Олег Цилюрик - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге QNX/UNIX: Анатомия параллелизма, автор: Олег Цилюрик. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x