nrw-rw-rw- 1 root root 0 Nov 09 23:17 /dev/wmng

Теперь подготовим простейший клиент:

void main(int argc, char *argv[]) {

 char sResName[_POSIX_PATH_MAX + 1] = '/dev/wmng';

 if (argc > 1) strcpy(sResName, argv[1]);

 int df = open(sResName, O_RDWR | O_NONBLOCK);

 if (df < 0)

  perror('device open'), exit(EXIT_FAILURE);

 cout << open << sResName

  << ' , desc. = ' << df << endl;

 char ibuf[2048], obuf[2048];

 int r, w;

 while (true) {

  if ((r = read(df, obuf, sizeof(obuf))) < 0) break;

  cout << '#' << obuf << endl; cout << '>' << flush;

  cin >> ibuf;

  if (( w = write(df, ibuf, strlen(ibuf) + 1)) <= 0) break;

 }

 if (r < 0) perror('read error');

 if (w <= 0) perror('write error');

 exit(EXIT_FAILURE);

}

Запустим одновременно 2 экземпляра клиента (их, собственно, может быть сколь угодно много) и убедимся, что каждый из клиентов работает со своей отдельной копией структур данных внутри процесса менеджера ресурса:

# wmclient

open /dev/wmng , desc. = 3 #

>1234

#1234

>54321

#54321

>

# wmclient

open /dev/wmng , desc. = 3

#

>qwerty

#qwerty

>asdf

#asdf >

Отчетливо видно, что каждый клиент с получением своего файлового дескриптора (реально это дескриптор соединения) получает и свой экземпляр данных.

Полную параллельность и независимость обращений (например, возможность выполнения read() в то время, когда менеджер занят выполнением read() от другого клиента) к данному псевдоустройству отследить сложнее. Для этого в код обработчиков операций чтения/записи следует внести ощутимую задержку (например, sleep() или delay() ) и воздействовать достаточно плотным потоком запросов со стороны нескольких клиентов. Такие эксперименты показывают полную независимость операций по разным файловым дескрипторам, что обеспечивается переопределением обработчика по умолчанию — iofunc_lock_ocb_default() .

Сообщения или менеджер?

Этот вопрос возникает (должен возникать!) у каждого, кто приступает к разработке реального проекта, особенно если функциональность проекта распределяется между несколькими автономными процессами. Такая структуризация и вовсе не привычна разработчикам, приходящим из мира Windows. Для UNIX создание проектов, в которых порождается несколько процессов, такая структуризация уже гораздо органичнее, но и там это чаще всего лишь клонирование образа единого серверного процесса посредством fork(). QNX предоставляет возможность идти еще дальше в построении приложений, представленных (разделенных) как группа разнородных взаимодействующих процессов:

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

• Процессы QNX сохраняют все качества таковых и в UNIX вообще: они являются изолированными сущностями, которые взаимодействуют, если это необходимо, используя достаточно тяжеловесные (расточительные) механизмы IPC. Собственно, в этом и ценность процессов с их изолированными адресными пространствами — это механизм обеспечения высокой надежности и живучести приложений. Но QNX, не сужая спектр общепринятых IPC-механизмов, привносит совершенно новый «слой» инструментария взаимодействия — обмен сообщениями микроядра. При этом «проницаемость» процессов как отдельных клеток живого организма становится много выше, нисколько не снижая их «защищенности».

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

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

Две стороны единого механизма

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

Для эффективного применения той или иной альтернативной технологии мы должны иметь

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату