MyBooks.club
Все категории

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

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

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

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

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

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

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

45   Sem_wait(shared.mutex);

46   shared.counter++;

47   Sem_post(shared.mutex);

48  }

49  return(NULL);

50 }

Листинг А.26. Функция main для измерения быстродействия именованных семафоров Posix

//bench/incr_pxsem2.с

1  #include "unpipc.h"

2  #define MAXNTHREADS 100

3  #define NAME "incr_pxsem2"


4  int nloop;

5  struct {

6   sem_t *mutex; /* указатель на именованный семафор */

7   long counter;

8  } shared;

9  void *incr(void *);


10 int

11 main(int argc, char **argv)

12 {

13  int i, nthreads;

14  pthread_t tid[MAXNTHREADS];

15  if (argc != 3)

16   err_quit("usage: incr_pxsem2 <#loops> <#threads>");

17  nloop = atoi(argv[1]);

18  nthreads = min(atoi(argv[2]), MAXNTHREADS);

19  /* инициализация именованного семафора 0 */

20  sem_unlink(Px_ipc_name(NAME)); /* ошибка – OK */

21  shared.mutex = Sem_open(Px_ipc_name(NAME), O_CREAT | O_EXCL, FILE_MODE, 0);

22  /* создание всех потоков */

23  Set_concurrency(nthreads);

24  for (i = 0; i < nthreads; i++) {

25   Pthread_create(&tid[i], NULL, incr, NULL);

26  }

27  /* запуск таймера и разблокирование семафора */

28  Start_time();

29  Sem_post(shared.mutex);

30  /* ожидание завершения всех потоков */

31  for (i = 0; i < nthreads; i++) {

32   Pthread_join(tid[i], NULL);

33  }

34  printf("microseconds: %.0f usecn", Stop_time());

35  if (shared.counter != nloop * nthreads)

36   printf("error: counter = %ldn", shared.counter);

37  Sem_unlink(Px_ipc_name(NAME));

38  exit(0);

39 }

Семафоры System V

Функция main программы, измеряющей быстродействие семафоров System V, приведена в листинге А.27, а функция incr показана в листинге А.28.

Листинг А.27. Функция main для измерения быстродействия семафоров System V

//bench/incr_svsem1.c

1  #include "unpipc.h"

2  #define MAXNTHREADS 100


3  int nloop;

4  struct {

5   int semid;

6   long counter;

7  } shared;

8  struct sembuf postop, waitop;

9  void *incr(void *);


10 int

11 main(int argc, char **argv)

12 {

13  int i, nthreads;

14  pthread_t tid[MAXNTHREADS];

15  union semun arg;

16  if (argc != 3)

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

18  nloop = atoi(argv[1]);

19  nthreads = min(atoi(argv[2]), MAXNTHREADS);

20  /* создание семафора и инициализация его значением 0 */

21  shared.semid = Semget(IPC_PRIVATE, 1, IPC_CREAT | SVSEM_MODE);

22  arg.val =0;

23  Semctl(shared.semid, 0, SETVAL, arg);

24  postop.sem_num = 0; /* инициализация двух структур semop */

25  postop.sem_op = 1;

26  postop.sem_flg = 0;

27  waitop.sem_num = 0;

28  waitop.sem_op = –1;

29  waitop.sem_flg = 0;

30  /* создание всех потоков */

31  Set_concurrency(nthreads);

32  for (i = 0; i < nthreads; i++) {

33   Pthread_create(&tid[i], NULL, incr, NULL);

34  }

35  /* запуск таймера и разблокирование семафора */

36  Start_time();

37  Semop(shared.semid, &postop, 1); /* up by 1 */

38  /* ожидание завершения всех потоков */

39  for (i = 0; i < nthreads; i++) {

40   Pthread_join(tid[i], NULL);

41  }

42  printf("microseconds: %.0f usecn", Stop_time());

43  if (shared.counter != nloop * nthreads)

44   printf("error: counter = %ldn", shared, counter);

45  Semctl(shared.semid, 0, IPC_RMID);

46  exit(0);

47 }

Листинг А.28. Увеличение общего счетчика с использованием семафоров System V

//bench/incr_svsem1.c

48 void *

49 incr(void *arg)

50 {

51  int i;

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

53   Semop(shared.semid, &waitop, 1);

54   shared.counter++;

55   Semop(shared.semid, &postop, 1);

56  }

57  return(NULL);

58 }

20-23 Создается семафор с одним элементом, значение которого инициализируется нулем.

24-29 Инициализируются две структуры semop: одна для увеличения семафора, а другая для ожидания его изменения. Обратите внимание, что поле sem_flg в обеих структурах имеет значение 0: флаг SEM_UNDO не установлен.

Семафоры System V с флагом SEM_UNDO

Единственное отличие от пpoгрaммы из листинга А.27 заключается в том, что поле sem_flg структур semop устанавливается равным SEM_UNDO, а не 0. Мы не приводим в книге новый листинг с этим небольшим изменением.

Блокировка записей fcntl

Последняя пpoгрaммa использует fcntl для синхронизации. Функция main приведена в листинге А.30. Эта программа будет выполняться успешно только в том случае, если количество потоков равно 1, поскольку блокировка fcntl предназначена для использования между процессами, а не между потоками одного процесса. При указании нескольких потоков каждый из них всегда имеет возможность получить блокировку (то есть вызовы writew_lock не приводят к остановке потока, потому что процесс уже является владельцем блокировки), и конечное значение счетчика оказывается неправильным.

Функция incr, использующая блокировку записей, приведена в листинге А.29.

Листинг А.29. Увеличение общего счетчика с использованием блокировки записей fcntl

//bench/incr_fcntl1.e

44 void *

45 incr(void *arg)

46 {

47  int i;

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

49   Writew_lock(shared.fd, 0, SEEK_SET, 0);

50   shared.counter++;

51   Un_lock(shared.fd, 0, SEEK_SET, 0);

52  }

53 return(NULL);

54 }

Листинг А.30. Функция main для измерения производительности блокировки fcntl

//bench/incr_fcntl1.e

4  #include "unpipc.h"

5  #define MAXNTHREADS 100


6  int nloop;

7  struct {

8   int fd;

9   long counter;

10 } shared;

11 void *incr(void *);


12 int

13 main(int argc, char **argv)

14 {

15  int i, nthreads;

16  char *pathname;

17  pthread_t tid[MAXNTHREADS];

18  if (argc != 4)

19   err_quit("usage: incr_fcntll <pathname> <#loops> <#threads>");

20  pathname = argv[1];

21  nloop = atoi(argv[2]);

22  nthreads = min(atoi(argv[3]), MAXNTHREADS);

23  /* создание файла и получение блокировки на запись */

24  shared.fd = Open(pathname, O_RDWR | O_CREAT | O_TRUNC, FILE_MODE);

25  Writew_lock(shared.fd, 0, SEEK_SET, 0);

26  /* создание всех потоков */

27  Set_concurrency(nthreads);

28  for (i = 0; i < nthreads; i++) {

29   Pthread_create(&tid[i], NULL, incr, NULL);

30  }

31  /* запуск таймера и снятие блокировки на запись */

32  Start_time();

33  Un_lock(shared.fd, 0, SEEK_SET, 0);

34  /* ожидание завершения всех потоков */

35  for (i = 0; i < nthreads; i++) {

36   Pthread_join(tid[i], NULL);

37  }

38  printf("microseconds: %.0f usecn", Stop_time());

39  if (shared.counter != nloop * nthreads)

40   printf("error: counter = %ldn", shared.counter);

41  Unlink(pathname);

42  exit(0);

43 }

15-19 Полное имя создаваемого и используемого для блокировки файла принимается в качестве аргумента командной строки. Это позволяет измерять скорость работы для разных файловых систем. Можно ожидать, что программа будет работать гораздо медленнее при использовании NFS (если она вообще будет работать, то есть если сервер и клиент NFS поддерживают блокировку записей NFS).

А.6. Синхронизация процессов: программы

В программах предыдущего раздела счетчик использовался несколькими потоками одного процесса. При этом он представлял собой глобальную переменную. Теперь нам нужно изменить эти программы для измерения скорости синхронизации различных процессов.

Для разделения счетчика между родительским процессом и дочерними мы помещаем его в разделяемую память, выделяемую функцией my_shm, показанной в листинге А.31.

Листинг А.31. Выделение разделяемой памяти под родительский и дочерние процессы

//lib/my_shm.c

1  #include "unpipc.h"


2  void *

3  my_shm(size_t nbytes)

4  {

5   void *shared;

6  #if defined(MAP_ANON)

7   shared = mmap(NULL, nbytes, PROT_READ | PROT_WRITE,

8   MAP_ANON | MAP_SHARED, –1, 0);

9  #elif defined(HAVE_DEV_ZERO)

10  int fd;

11  /* отображение в память файла /dev/zero */

12  if ((fd = open("/dev/zero", O_RDWR)) == –1)

13   return(MAP_FAILED);

14  shared = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

15  close(fd);

16 #else

17 # error cannot determine what type of anonymous shared memory to use

18 #endif

19  return(shared); /* ошибка отображения в память */

20 }

Если система поддерживает флаг MAP_ANON (раздел 12.4), мы используем этот тип разделяемой памяти. В противном случае используется отображение в память файла /dev/zero (раздел 12.5).


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

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


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

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

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