Стивенс Уильям Ричард
Шрифт:
20 arg.data_size = sizeof(square_in);
21 arg.desc_ptr = NULL;
22 arg.desc_num = 0;
23 arg.rbuf = (char*)&square_out;
24 arg.rsize = sizeof(square_out);
25 Door_call(fdsquare, &arg);
26 /* подготовка аргументов и вызов sqrtproc */
27 sqrt_in.arg1 = atol(argv[1]);
28 arg.data_ptr = (char*)&sqrt_in;
29 arg.data_size = sizeof(sqrt_in);
30 arg.desc_ptr = NULL;
31 arg.desc_num = 0;
32 arg.rbuf = (char*)&sqrt_out;
33 arg.rsize = sizeof(sqrt_out);
34 Door_call(fdsqrt, &arg);
35 printf("result: %ld %g\n", square_out.res1, sqrt_out.res1);
36 exit(0);
37 }
Текст двух серверных процедур приведен в листинге 15.11. Каждая из них выводит текущий идентификатор потока и значение аргумента, делает 5-секунд-ную паузу, вычисляет результат и завершает работу.
Листинг 15.11. Две процедуры сервера
//doors/server7.c
1 #include "unpipc.h"
2 #include <math.h>
3 #include "squareproc.h"
4 #include "sqrtproc.h"
5 void
6 squareproc(void *cookie, char *dataptr, size_t datasize,
7 door_desc_t *descptr, size_t ndesc)
8 {
9 squareproc_in_t in;
10 squareproc_out_t out;
11 memcpy(&in, dataptr, min(sizeof(in), datasize));
12 printf("squareproc: thread id %ld, arg = %ld\n",
13 pr_thread_id(NULL), in.arg1);
14 sleep(5);
15 out.res1 = in.arg1 * in.arg1;
16 Door_return((char *) &out, sizeof(out), NULL, 0);
17 }
18 void
19 sqrtproc(void *cookie, char *dataptr, size_t datasize,
20 door_desc_t *descptr, size_t ndesc)
21 {
22 sqrtproc_in_t in;
23 sqrtproc_out_t out;
24 memcpy(&in, dataptr, min(sizeof(in), datasize));
25 printf("sqrtproc: thread id %ld, arg = %ld\n",
26 pr_thread_id(NULL), in.arg1);
27 sleep(5);
28 out.res1 = sqrt((double)in.arg1);
29 Door_return((char *) &out, sizeof(out), NULL, 0);
30 }
Функция main сервера, текст которой приведен в листинге 15.12, открывает дескрипторы дверей и связывает каждый из них с одной из процедур сервера.
Листинг 15.12. Функция main сервера
//doors/server7.c
31 int
32 main(int argc, char **argv)
33 {
34 int fd;
35 if (argc != 1)
36 err_quit("usage: server7");
37 fd = Door_create(squareproc, NULL, 0);
38 unlink(PATH_SQUARE_DOOR);
39 Close(Open(PATH_SQUARE_DOOR, O_CREAT | O_RDWR, FILE_MODE));
40 Fattach(fd, PATH_SQUARE_DOOR);
41 fd = Door_create(sqrtproc, NULL, 0);
42 unlink(PATH_SQRT_DOOR);
43 Close(Open(PATH_SQRT_DOOR, O_CREAT | O_RDWR, FILE_MODE));
44 Fattach(fd, PATH_SQRT_DOOR);
45 for (;;)
46 pause;
47 }
Запустим программу-клиент и подождем 10 секунд до вывода результатов (как мы и ожидали):
solaris % client7 77
result: 5929 8.77496
Посмотрев на выводимый сервером текст, мы увидим, что один и тот же поток этого процесса использовался для обработки обоих запросов клиента:
solaris % server7
squareproc: thread id 4, arg = 77