Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:
Листинг 15.10. Клиент, вызывающий две процедуры

//doors/client7.c

1 #include "unpipc.h"

2 #include "squareproc.h"

3 #include "sqrtproc.h"

4 int

5 main(int argc, char **argv)

6 {

7 int fdsquare, fdsqrt;

8 door_arg_t arg;

9 squareproc_in_t square_in;

10 squareproc_out_t square_out;

11 sqrtproc_in_t sqrt_in;

12 sqrtproc_out_t sqrt_out;

13 if (argc != 2)

14 err_quit("usage: client7 <integer-value>");

15 fdsquare = Open(PATH_SQUARE_DOOR, O_ROWR);

16 fdsqrt = Open(PATH_SQRT_DOOR, O_RDWR);

17 /*
подготовка аргументов и вызов squareproc */

18 square_in.arg1 = atol(argv[1]);

19 arg.data_ptr = (char*)&square_in;

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

sqrtproc: thread id 4, arg = 77

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

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

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

Поделиться с друзьями: