Читаем UNIX Network Programming. Volume 2 Second Edition. Interprocess Communications полностью

16-17 Вызов valloc аналогичен malloc, но выделяемая память начинается с границы страницы памяти. Функция touch (листинг А.3) помещает 1 байт данных в каждую страницу буфера, заставляя ядро считать в память все страницы данного буфера. Мы всегда выполняем это перед проведением измерений.

ПРИМЕЧАНИЕ

Функция valloc не входит в стандарт Posix.1 и названа устаревшей в Unix 98. Она требовалась в ранних версиях спецификаций Х/Open, но уже не является необходимой. Обертка Valloc вызывает функцию malloc, если valloc недоступна.

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

18-19 Создаются два канала: contpipe[0] и contpipe[1] используются для синхронизации процессов перед началом передачи, a datapipe[0] и datapipe[1] используются для передачи самих данных.

Вызов fork

20-31 Создается дочерний процесс, вызывающий функцию writer, а родительский процесс в это время вызывает функцию reader. Функция reader вызывается nlоор раз. Функция start_time вызывается непосредственно перед началом цикла, a stop_time — сразу после его окончания. Эти функции даны в листинге А.З. Полоса пропускания представляет собой количество байтов, переданных за все проходы цикла, поделенное на время, затраченное на передачу (stop_time возвращает количество микросекунд, прошедшее с момент запуска start_time). Затем дочерний процесс завершается сигналом SIGTERM и программа завершает свою работу. Вторая половина программы приведена в листинге А.2. Она состоит из функций reader и writer.

Листинг А.2. Функции reader и writer

//bench/bw_pipe.cvoid

33 void

34 writer(int contfd, int datafd)

35 {

36  int ntowrite;

37  for(;;) {

38   Read(contfd, ntowrite, sizeof(ntowrite));

39   while (ntowrite 0) {

40    Write(datafd, buf, xfersize);

41    ntowrite –= xfersize;

42   }

43  }

44 }


45 void

46 reader(int contfd, int datafd, int nbytes)

47 {

48  ssize_t n;

49  Write(contfd, nbytes, sizeof(nbytes));

50  while ((nbytes 0)

51   ((n = Read(datafd, buf, xfersize)) 0)) {

52   nbytes –= n;

53  }

54 }

Функция writer

33-44 Функция writer представляет собой бесконечный цикл, вызываемый дочерним процессом. Он ожидает сообщения родительского процесса о готовности к приему данных, считывая целое число из управляющего канала. Это целое число определяет количество байтов, которое будет записано в канал данных. При получении этого числа дочерний процесс записывает данные в канал, отправляя их родителю. За один вызов write записывается xfersize байтов.

Функция reader

45-54 Эта функция вызывается родительским процессом в цикле. Каждый раз при вызове функции в управляющий канал записывается целое число, указывающее дочернему процессу на необходимость помещения соответствующего количества данных в канал данных. Затем функция вызывает read в цикле до тех пор, пока не будут приняты все данные.

Текст функций start_time, stop_time и touch приведен в листинге А.З.

Листинг А.З. Функции start_sime, stop_time и touch

//lib/timing.с

1  #include "unpipc.h"

2  static struct timeval tv_start, tv_stop;


3  int

4  start_time(void)

5  {

6   return(gettimeofday(tv_start, NULL));

7  }


8  double

9  stop_time(void)

10 {

11  double clockus;

12  if (gettimeofday(tv_stop, NULL) == –1)

13   return(0.0);

14  tv_sub(tv_stop, tv_start);

15  clockus = tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec;

16  return(clockus);

17 }


18 int

19 touch(void *vptr, int nbytes)

20 {

21  char *cptr;

22  static int pagesize = 0;

23  if (pagesize == 0) {

24   errno = 0;

25 #ifdef _SC_PAGESIZE

26   if ((pagesize = sysconf(_SC_PAGESIZE)) == –1)

27    return(-1);

28 #else

29   pagesize = getpagesize; /* BSD */

30 #endif

31  }

32  cptr = vptr;

33  while (nbytes 0) {

34   *cptr = 1;

35   cptr += pagesize;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже