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

ЖАНРЫ

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

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

Шрифт:

17 totalnbytes = atoi(argv[3]) * 1024 * 1024;

18 xfersize = atoi(argv[4]);

19 buf = Valloc(xfersize);

20 Touch(buf, xfersize);

21 unlink(argv[1]);

22 Close(Open(argv[1], O_CREAT | O_EXCL | O_RDWR, FILE_MODE));

23 Pipe(contpipe); /* предполагается наличие двустороннего канала SVR4 */

24 if ((childpid = Fork) == 0) {

25 /* дочерний процесс = клиент */

26 if ((n = Read(contpipe[0], &c, 1)) != 1)

27 err_quit("child: pipe read returned %d", n);

28 doorfd = Open(argv[1], O_RDWR);

29 writer(doorfd);

30 exit(0);

31 }

32 /*
родительский процесс = сервер */

33 doorfd = Door_create(server, NULL, 0);

34 Fattach(doorfd, argv[1]);

35 Write(contpipe[1], &c, 1); /* уведомление о готовности двери */

36 Start_time;

37 for (i = 0; i < nloop; i++)

38 reader(doorfd, totalnbytes);

39 printf("bandwidth: %.3f MB/sec\n",

40 totalnbytes / Stop_time * nloop);

41 kill(childpid, SIGTERM);

42 unlink(argv[1]);

43 exit(0);

44 }

Листинг A.10. Функции writer, server, reader для интерфейса дверей

//bench/bw_door.c

45 void

46 writer(int doorfd)

47 {

48 int ntowrite;

49 door_arg_t arg;

50 arg.desc_ptr = NULL; /* дескрипторы не передаются */

51 arg.desc_num = 0;

52 arg.rbuf = NULL; /* значения не возвращаются */

53 arg.rsize = 0;

54 for(;;) {

55 Read(contpipe[0], &ntowrite, sizeof(ntowrite));

56 while (ntowrite > 0) {

57 arg.data_ptr = buf;

58 arg.data_size = xfersize;

59 Door_call(doorfd, &arg);

60 ntowrite –= xfersize;

61 }

62 }

63 }

64 static int ntoread, nread;

65 void

66 server(void *cookie, char *argp, size_t arg_size,

67 door_desc_t *dp, size_t n_descriptors)

68 {

69 char c;

70 nread += arg_size;

71 if (nread >= ntoread)

72 Write(contpipe[0], &c, 1); /* запись закончена */

73 Door_return(NULL, 0, NULL, 0);

74 }

75 void

76 reader(int doorfd, int nbytes)

77 {

78 char c;

79 ssize_t n;

80 ntoread = nbytes; /*
глобальные переменные процедуры сервера */

81 nread = 0;

82 Write(contpipe[1], &nbytes, sizeof(nbytes));

83 if ((n = Read(contpipe[1], &c, 1)) != 1)

84 err_quit("reader: pipe read returned %d", n);

85 }

Программа определения полосы пропускания Sun RPC

Поскольку вызовы процедур в Sun RPC являются синхронными, для них действует то же ограничение, что и для дверей (см. выше). В данном случае проще создать две программы (клиент и сервер), поскольку они создаются автоматически программой rpcgen. В листинге А.11 приведен файл спецификации RPC. Мы объявляем единственную процедуру, принимающую скрытые данные переменной длины в качестве входного аргумента и ничего не возвращающую.

В листинге А.12 приведен текст программы-клиента, а в листинге А.13 — процедура сервера. Мы указываем протокол в качестве аргумента командной строки при вызове клиента, что позволяет нам измерить скорость работы обоих протоколов.

Листинг А.11. Спецификация RPC для измерения полосы пропускания RPC

//bench/bw_sunrpc.х

1 %#define DEBUG /* сервер выполняется в приоритетном режиме */

2 struct data_in {

3 opaque data<>; /* скрытые данные переменной длины */

4 };

5 program BW_SUNRPC_PROG {

6 version BW_SUNRPC_VERS {

7 void BW_SUNRPC(data_in) = 1;

8 } = 1;

9 } = 0x31230001;

Листинг A.12. Клиент RPC для измерения полосы пропускания

//bench/bw_sunrpc_client.с

1 #include "unpipc.h"

2 #include "bw_sunrpc.h"

3 void *buf;

4 int totalnbytes, xfersize;

5 int

6 main(int argc, char **argv)

7 {

8 int i, nloop, ntowrite;

9 CLIENT *cl;

10 data_in in;

11 if (argc != 6)

12 err_quit("usage: bw_sunrpc_client <hostname> <#loops>"

13 " <#mbytes> <#bytes/write> <protocol>");

14 nloop = atoi(argv[2]);

15 totalnbytes = atoi(argv[3]) * 1024 * 1024;

16 xfersize = atoi(argv[4]);

17 buf = Valloc(xfersize);

18 Touch(buf, xfersize);

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