Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 [ 120 ] 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

3 servprocCvoid *cookie, char *dataptr, size t datasize.

4 door desc t *descptr, size t ndesc)

6 long arg, result;

7 arg = *((long *) dataptr):

8 result = arg * arg:

9 Door return((char *) Sresult, sizeof(result), NULL. 0);

10 }

11 int

12 ttiain(int argc, char **argv)

13 {

14 int fd:

15 if (argc != 2)

16 err quit( usage; serverl <server-pathnattie> );

17 /* создание двери и связывание ее с файлом */

18 fd = Door create(servproc, NULL, 0);

19 unlink(argv[l]);

20 Close(Open(argv[l], 0 CREAT 0 RDWR, FILE MODE));

21 Fattach(fd, argv[l]);

22 /* функция servprocO обрабатывает все запросы клиентов */

23 for ( ; : )

24 pauseO;

25 }

Процедура сервера

2-10 Процедура сервера вызывается с пятью аргументами, но мы используем только один из них - dataptr. Он указывает на первый байт аргумента. Аргумент, представляющий собой длинное целое, передается через этот указатель и возводится в квадрат. Управление передается клиенту вместе с результатом вызовом door return. Первый аргумент указывает на результат, второй задает его размер, а оставшиеся предназначены для возврата дескрипторов.

Создание дескриптора двери и связывание с ним файла

17-21 Дескриптор двери создается вызовом doorcreate. Первый аргумент является указателем на функцию, соответствующую этой двери (servproc). После получения этого дескриптора его нужно связать с некоторым именем в файловой системе, поскольку оно будет использоваться клиентом для подключения к этой двери. Делается это njrreM создания обычного файла в файловой системе (сначала мы вызываем unl i nk, на тот случай, если такой файл уже существует, причем возможная ошибка игнорируется) и вызова fattach - функции SVR4, связывающей дескриптор с полным именем файла.

Главный поток сервера ничего не делает

22-24 Главный поток сервера блокируется при вызове ра use. Вся функциональность обеспечивается функцией servproc, которая будет запускаться как отдельный поток каждый раз при получении запроса клиента.



Запустим сервер в отдельном окне: Solaris % serverl /tttip/serverl

После этого запустим программу-клиент в другом окне, указав в качестве аргумента то же полное имя, которое было указано при вызове сервера:

Solaris % cl Ientl /tttip/serverl 9

result: 81

Solaris * Is -1 /tttip/serverl

Orw-r--r-- 1 rstevens otherl 0 Apr 9 10:09 /tttip/serverl

Мы получили ожидаемый результат. Вызвав 1 s, мы видим, что эта программа

выводит букву D в начале строки, соответствующей файлу, указывая, что этот файл

является дверью.

На рис. 15.2 приведена диаграмма работы данного примера. Функция doorcal 1 вызывает процедуру на сервере, которая затем вызывает doorreturn для возврата.

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

сервер

клиент

main ( )

fd = open (path, door caii (fd, );


servproc ( )

Г do whatever */ door retum ( );

main ( )

fd = door create ( ); fattach (fd, path);

Рис. 15.2. Внешний вид вызова процедуры в другом процессе

3. 4.

На рис. 15.3 выполняются следующие действия:

Запускается сервер, вызывает door create, чтобы создать дескриптор для функции servproc, затем связывает этот дескриптор с именем файла в файловой системе.

Запускается клиент и вызывает door cal 1. Это функция в библиотеке дверей.

Библиотечная функция door call делает системный вызов. При этом указывается процедура, которая должна быть выполнена, а управление передается функции из библиотеки дверей процесса-сервера.

Вызывается процедура сервера (servproc в данном примере).

Процедура сервера делает все необходимое для обработки запроса клиента

и вызывает door return по завершении работы.

Библиотечная функция door return осуществляет системный вызов, передавая управление ядру.

В этом вызове указывается процесс-клиент, которому и передается управление.



сервер

клиент

main ( ) {

fd = open (path, ); door call (fd, );


. библиотека j I дверей >

servproc ( ) -<-

/* do whatever */ door retum ( ); - } 4

main ( ) {

fd = door create ( ); fattach (fd, path);


Рис. 15.3. Что в действительности происходит при вызове процедуры в другом процессе

Последующие разделы этой главы описывают интерфейс дверей (doors API) более подробно, с множеством примеров, В приложении А мы убедимся, что двери представляют собой наиболее быструю форму IPC (при измерении времени ожидания).

15.2. Функция door call

Функция door call вызывается клиентом для обращения к процедуре сервера, выполняемой в адресном пространстве процесса-сервера: finclude <door.h>

int door call(int fd, door arg t *argp)\

I* Возвращает 0 в случае успешного завершения, -1 - в случае ошибки */ Дескриптор fd обычно возвращается функцией open (см, листинг 15.1), Полное имя файла, открываемого клиентом, однозначно идентифицирует процедуру сервера, которая вызывается door cal 1 при передаче дескриптора.

Второй аргумент - argp - указывает на структуру, описывающую аргументы и приемный буфер для возвращаемых значений:

typedef struct door arg {

char *data ptr: /* при вызове указывает на аргументы, при возврате - на результаты */ size t data size; /* при вызове определяет общий размер аргументов в байтах, при возврате - общий размер возвращаемых данных в байтах */



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 [ 120 ] 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.