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

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

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

Листинг 15.11. Две процедуры сервера

doors/server?.с

1 finclude unpipc.h

2 finclude <math.h>

3 finclude squareproc.h

4 finclude sqrtproc.h

5 void

6 squareprocCvoid *cookie. char *dataptr. size t datasize,

7 door desc t *descptr. size t ndesc)

9 squareprocJn t in:

10 squareproc out t out:

11 memcpy(&in. dataptr. min(sizeof(in). datasize)):

12 printfC squareproc: thread id *ld. arg = *ld\n .

13 prjhreadjd (NULL), in.argl):

14 sleep(5):

15 out.resl = in.argl * in.argl:

16 Door return((char *) &out. sizeof(out). NULL, 0):

17 }

18 void

19 sqrtprocCvoid *cookie. char *dataptr. sizej datasize.

20 door descJ *descptr, sizeJ ndesc)

21 {

22 sqrtproc inJ in;

23 sqrtproc outJ out:

24 memcpy(&in, dataptr. min(sizeof(in). datasize)):

25 printfC sqrtproc: thread id arg = ld\n ,

26 prJhreadJd(NULL). in.argl):

27 sleep(5):

28 out.resl = sqrt((double) in.argl):

29 Door return((char *) &out. sizeof(out), NULL. 0);

30 }

Функция main сервера, текст которой приведен в листинге 15.12, открывает дескрипторы дверей и связывает каждый из них с одной из процедур сервера.

Листинг 15.12. Функция main сервера

doors/server7.c

31 int

32 mainCint argc, char **argv)

33 {

34 int fd:

35 if Cargc != 1)

36 err quitC usage: server7 ):



37 fd = Door create(squareproc. NULL. 0):

38 unlink(PATH SQUARE DOOR):

39 Close(Open(PATH SQUARE DOOR, 0 CREAT 0 RDWR. FILE MODE)):

40 FattachCfd. PATH SQUARE DOOR);

41 fd = Door create(sqrtproc. NULL. 0):

42 unlink(PATH SQRT DOOR);

43 Close(Open(PATH SQRT DOOR. 0 CREAT 0 RDWR, FILE MODE)):

44 FattachCfd. PATH SQRT DOOR):

45 for ( : : )

46 pauseO;

47 }

Запустим программу-клиент и подождем 10 секунд до вывода результатов (как мы и ожидали):

Solaris X client7 77 result: 5929 8.77496

Посмотрев на выводимый сервером текст, мы увидим, что один и тот же поток

этого процесса использовался для обработки обоих запросов клиента:

Solaris X server7

squareproc: thread id 4. arg = 77

sqrtproc: thread id 4. arg = 77

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

Атрибут DOOR UNREF для серверов

в разделе 15.3 мы отметили, что при вызове cloor create для создаваемой двери можно указать атрибут DOOR UNREF. В документации говорится, что если количество дескрипторов, относящихся к этой двери, уменьшается с двух до одного, осуществляется специальный вызов процедуры сервера. Особенность вызова заключается в том, что второй аргумент процедуры сервера (указатель на данные) при этом является константой DOOR UNREF DATA. Мы продемонстрируем три способа обращения к двери.

1. Дескриптор, возвращаемый cloor create, считается первой ссылкой на эту дверь. Вообще говоря, причина, по которой специальный вызов происходит при изменении количества дескрипторов с 2 на 1, а не с 1 на О, заключается в том, что первый дескриптор обычно не закрывается сервером до завершения работы.

2. Полное имя, связанное с дверью в файловой системе, также считается ссылкой на дверь. Ее можно удалить вызовом функции f detach, или запустив программу f detach, или удалив полное имя из файловой системы (функцией unlink или командой гт).

3. Дескриптор, возвращаемый клиенту функцией open, считается открытой ссылкой до тех пор, пока не будет закрыт либо явным вызовом с1 ose, либо неявно, при завершении клиента. Во всех примерах этой главы дескриптор закрывается неявно.



Первый пример показывает, что если сервер закрывает свой дескриптор после вызова fattach, немедленно происходит специальный вызов процедуры сервера. В листинге 15.13 приведен текст процедуры сервера и функции main.

Листинг 15.13. Процедура сервера, обрабатывающая специальный вызов

doors/serverunrefl.с

1 finclude unpipc.h

2 void

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

4 door desc t *descptr. size t ndesc)

6 long arg. result;

7 if Cdataptr == DOOR UNREF DATA) {

8 printfC door unreferenced\n ):

9 Door returnCNULL. 0,NULL, 0);

10 }

11 arg = *CClong *) dataptr);

12 printfC thread id %Ы. arg = ld\n . pr thread idCNULL). arg):

13 sleepC6):

14 result = arg * arg:

15 Door returnCCchar *) &result. sizeofCresult), NULL. 0):

16 }

17 int

18 mainCint argc. char **argv)

19 {

20 int fd:

21 if Cargc != 2)

22 err quitC usage: serverl <server-pathname> ):

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

24 fd = Door createCservproc. NULL. DOORJNREF):

25 unlinkCargv[l]):

26 CloseCOpenCargvEl]. 0 CREAT 0 RDWR, FILE MODE)):

27 FattachCfd. argv[l]):

28 CloseCfd):

29 /* процедура servprocC) обрабатывает все запросы клиентов */

30 for С : : )

31 pauseC):

32 }

7-10 Процедура сервера распознает специальный вызов и выводит сообщение об этом. Возврат из специального вызова происходит путем вызова cloor return с двумя нулевыми указателями и нулевыми значениями размеров. 28 Теперь мы закрываем дескриптор двери после выполнения fattach. Этот дескриптор может быть нужен серверу только для вызовов cloor bincl, doorinfo и door revoke.



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.
Копирование материалов разрешено исключительно при условии цититирования.