My-library.info
Все категории

Уильям Стивенс - UNIX: взаимодействие процессов

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе Уильям Стивенс - UNIX: взаимодействие процессов. Жанр: Программирование издательство -, год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
UNIX: взаимодействие процессов
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
17 сентябрь 2019
Количество просмотров:
232
Читать онлайн
Уильям Стивенс - UNIX: взаимодействие процессов

Уильям Стивенс - UNIX: взаимодействие процессов краткое содержание

Уильям Стивенс - UNIX: взаимодействие процессов - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info
Книга написана известным экспертом по операционной системе UNIX и посвящена описанию одной из форм межпроцессного взаимодействия, IPC, с использованием которой создается большинство сложных программ. В ней описываются четыре возможности разделения решаемых задач между несколькими процессами или потоками одного процесса: передача сообщений, синхронизация, разделяемая память, удаленный вызов процедур.Книга содержит большое количество иллюстрирующих примеров и может использоваться как учебник по IPC, и как справочник для опытных программистов.

UNIX: взаимодействие процессов читать онлайн бесплатно

UNIX: взаимодействие процессов - читать книгу онлайн бесплатно, автор Уильям Стивенс

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/secn",

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);

19  cl = Clnt_create(argv[1], BW_SUNRPC_PROG, BW_SUNRPC_VERS, argv[5]);

20  Start_time();

21  for (i = 0; i < nloop; i++) {

22   ntowrite = totalnbytes;

23   while (ntowrite > 0) {

24    in.data.data_len = xfersize;

25    in.data.data_val = buf;

26    if (bw_sunrpc_1(&in, cl) == NULL)

27     err_quit("%s", clnt_sperror(cl, argv[1]));

28    ntowrite –= xfersize;

29   }

30  }

31  printf("bandwidth: %.3f MB/secn",

32   totalnbytes / Stop_time() * nloop);

33  exit(0);

34 }

Листинг A.13. Процедура сервера для измерения полосы пропускания RPC

//bench/bw_sunrpc_server.c

1  #include "unpipc.h"

2  #include "bw_sunrpc.h"

3  #ifndef RPCGEN_ANSIC

4  #define bw_sunrpc_1_svc bw_sunrpc_1

5  #endif


6  void *

7  bw_sunrpc_1_svc(data_in *inp, struct svc_req *rqstp)

8  {

9   static int nbytes;

10  nbytes = inp->data.data_len;

11  return(&nbytes); /* должен быть ненулевым, но xdr_void игнорирует */

12 }

А.4. Измерение задержки передачи сообщений: программы

Приведем текст трех программ, измеряющих задержку при передаче сообщений по каналам, очередям Posix и очередям System V. Данные о производительности, полученные с их помощью, приведены в табл. А.1.

Программа измерения задержки канала

Программа для измерения задержки канала приведена в листинге А.14.

Листинг А.14. Программа измерения задержки канала

//bench/lat_pipe.c

1  #include "unpipc.h"


2  void

3  doit(int readfd, int writefd)

4  {

5   char c;

6   Write(writefd, &c, 1);

7   if (Read(readfd, &c, 1) != 1)

8    err_quit("read error");

9  }


10 int

11 main(int argc, char **argv)

12 {

13  int i, nloop, pipe1[2], pipe2[2];

14  char c;

15  pid_t childpid;

16  if (argc != 2)

17   err_quit("usage: lat_pipe <#loops>");

18  nloop = atoi(argv[1]);

19  Pipe(pipe1);

20  Pipe(pipe2);

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

22   for(;;) { /* дочерний процесс */

23    if (Read(pipe1[0], &c, 1) != 1)

24     err_quit("read error");

25    Write(pipe2[1], &c, 1);

26   }

27   ехit(0);

28  }

29  /* родительский процесс */

30  doit(pipe2[0], pipe1[1]);

31  Start_time();

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

33   doit(pipe2[0], pipe1[1]);

34  printf("latency: %.3f usecn", Stop_time() / nloop);

35  Kill(childpid, SIGTERM);

36  exit(0);

37 }

Функция doit

2-9 Эта функция запускается родительским процессом. Мы измеряем время ее работы. Она помещает 1 байт в канал, из которого читает дочерний процесс, и считывает 1 байт из другого канала, в который сообщение помещается дочерним процессом. При этом измеряется именно то, что мы назвали задержкой, — время передачи небольшого сообщения туда и обратно.

Создание каналов

19-20 Создаются два канала, после чего вызов fork порождает дочерний процесс. При этом образуется схема, изображенная на рис. 4.6 (но без закрытия неиспользуемых дескрипторов каналов). Для этого теста требуются два канала, поскольку каналы являются односторонними, а мы хотим передавать сообщение в обе стороны.

Дочерний процесс отсылает обратно сообщение

22-27 Дочерний процесс представляет собой бесконечный цикл, в котором однобайтовое сообщение считывается и отсылается обратно.

Измерение времени работы родительского процесса

29-34 Родительский процесс вызывает функцию doit для отправки однобайтового сообщения дочернему процессу и получения ответа. После этого мы имеем гарантию, что оба процесса выполняются. Затем функция doit вызывается в цикле с измерением времени задержки.

На компьютере Sparc под управлением Solaris 2.6 при запуске программы пять раз подряд мы получим вот что:

solaris % lat_pipe 10000

latency: 278.633 usec

solaris % lat_pipe 10000

latency: 397.810 usec

solaris % lat_pipe 10000

latency: 392.567 usec

solaris % lat_pipe 10000

latency: 266.572 usec

solaris % lat_pipe 10000

latency: 284.559 usec

Среднее для пяти попыток составляет 324 микросекунды, и именно это значение приведено в табл. А.1. Это время учитывает два переключения контекста (от родительского процесса к дочернему и обратно), четыре системных вызова (write, read, write, read) и затраты на передачу 1 байта данных по каналу.

Программа измерения задержки очередей сообщений Posix


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


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

Отзывы читателей о книге UNIX: взаимодействие процессов, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.