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

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

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

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

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

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

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

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

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

18   Close(pipe1[1]); /* child */

19   Close(pipe2[0]);

20   mqid = Msgget(Ftok(argv[1], 0), MSG_R);

21   for(;;) {

22    /* блокируется в ожидании, извещает родительский процесс */

23    nread = Msgrcv(mqid, buff, MAXMSG, 0, 0);

24    Write(pipe2[1], &nread, sizeof(ssize_t));

25    /* ожидает разрешения родительского процесса */

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

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

28   }

29   exit(0);

30  } /* $$.bp$$ */

31  /* parent */

32  Close(pipe1[0]);

33  Close(pipe2[1]);

34  FD_ZERO(&rset);

35  FD_SET(pipe2[0], &rset);

36  for(;;) {

37   if ((n = select(pipe2[0] + 1, &rset, NULL, NULL, NULL)) != 1)

38    err_sys("select returned %d", n);

39   if (FD_ISSET(pipe2[0], &rset)) {

40    n = Read(pipe2[0], &nread, sizeof(ssize_t)); /* *INDENT-OFF* */

41    if (n != sizeof(ssize_t))

42     err_quit("parent: read on pipe returned %d", n); /* *INDENT-ON* */

43    printf("read %d bytes, type = %ldn", nread, buff->mtype);

44    Write(pipe1[1], &c, 1);

45   } else

47  }

46  err_quit("pipe2[0] not ready");

48  Kill(childpid, SIGTERM);

49  exit(0);

50 }

Глава 13

1. В листинге Г.8 приведен текст измененной версии листинга 12.6, а в листинге Г.9 — текст новой версии листинга 12.7. Обратите внимание, что в первой пpoгрaммe мы устанавливаем размер объекта вызовом ftruncate; lseek и write использовать для этого нельзя.

Листинг Г.8. Отображение с точным указанием размера файла

//pxshra/test1.c

1  #include "unpipc.h"


2  int

3  main(int argc, char **argv)

4  {

5   int fd, i;

6   char *ptr;

7   size_t shmsize, mmapsize, pagesize;

8   if (argc != 4)

9    err_quit("usage: test1 <name> <shmsize> <mmapsize>");

10  shmsize = atoi(argv[2]);

11  mmapsize = atoi(argv[3]);

12  /* открываем shm: создание или урезание; установка размера */

13  fd = Shm_open(Px_ipc_name(argv[1]), O_RDWR | O_CREAT | O_TRUNC,

14   FILE_MODE);

15  Ftruncate(fd, shmsize); /* $$.bp$S */

16  ptr = Mmap(NULL, mmapsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

17  Close(fd);

18  pagesize = Sysconf(_SC_PAGESIZE);

19  printf("PAGESIZE = %ldn", (long) pagesize);

20  for (i = 0; i < max(shmsize, mmapsize); i += pagesize) {

21   printf("ptr[%d] = %dn", i, ptr[i]);

22   ptr[i] = 1;

23   printf("ptr[%d] = %dn", i + pagesize – 1, ptr[i + pagesize – 1]);

24   ptr[i + pagesize – 1] = 1;

25  }

26  printf("ptr[%d] =%dn", i, ptr[i]);

27  exit(0);

28 }

Листинг Г.9. Отображение в память с возможностью роста файла

//pxshm/test2.c

1  #include "unpipc.h"

2  #define FILE "test.data"

3  #define SIZE 32768


4  int

5  main(int argc, char **argv)

6  {

7   int fd, i;

8   char *ptr;

9   /* создаем или урезаем, отображаем */

10  fd = Shm_open(Px_ipc_name(FILE), O_RDWR | O_CREAT | O_TRUNC, FILE_MODE);

11  ptr = Mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

12  for (i = 4096; i <= SIZE; i += 4096) {

13   printf("setting shm size to %dn", i);

14   Ftruncate(fd, i);

15   printf("ptr[%d] = %dn", i-1, ptr[i-1]);

16  }

17  exit(0);

18 }

2. Одна из возможных проблем при использовании *ptr++ заключается в том, что указатель, возвращенный mmap, изменяется, что может помешать впоследствии вызвать munmap. Если этот указатель еще понадобится, лучше его сохранить или вовсе не изменять.

Глава 14

1. Нужно изменить только одну строку:

13с13

< id = Shmget(Ftok(argv[1], 0), 0, SVSHM_MORE);

> id = atol(argv[1]);

Глава 15

1. Аргументы будут иметь размер data_size + (desc_numxsizeof(door_desc_t)) байт.

2. Вызывать fstat не нужно. Если дескриптор не указывает на дверь, вызов door_infо возвращает ошибку EBADF:

solaris % doorinfo /etc/passwd

door_info error: Bad file number

3. Документация содержит неверные сведения. Стандарт Posix утверждает, что функция sleep приведет к приостановке вызвавшего потока.

4. Результат непредсказуем (хотя, скорее всего, будет выполнен дамп памяти), поскольку адрес процедуры сервера, связанной с дверью, в новом процессе будет указывать на совершенно случайную область памяти.

5. При завершении door_call из-за перехвата сигнала сервер следует уведомить об этом, поскольку поток, работающий с этим клиентом, получит запрос на отмену выполнения. В связи с листингом 15.18 мы говорили, что отмена для создаваемых библиотекой потоков по умолчанию отключена, следовательно, поток завершен не будет. Вместо этого происходит досрочный возврат из вызова sleep(6) в процедуре сервера, но она продолжает выполняться.

6. Вот что мы увидим:

solaris % server6 /tmp/door6

my_thread: created sever thread 4

door_bind error: Bad file number

Запустив сервер 20 раз подряд, мы получим 5 сообщений об ошибке. Предсказать такую ошибку заранее нельзя.

7. Нет. Все, что нужно, — включать возможность отмены каждый раз при вызове процедуры сервера, как мы делали в листинге 15.26. Хотя в этом случае и приходится вызывать pthread_setcancelstate каждый раз при запуске процедуры сервера, накладные расходы, скорее всего, будут невелики.

8. Чтобы проверить это, изменим код одного из серверов (скажем, из листинга 15.6) так, чтобы он вызывал door_revoke из процедуры сервера. Поскольку аргументом door_revoke является дескриптор двери, его придется сделать глобальным. Вот что получится при запуске клиента (из листинга 15.1) два раза подряд:

solaris % client8 /tmp/door8 88

result: 7744

solaris % client8 /tmp/door8 99

door_call error: Bad file number

Первый вызов завершается успешно, что подтверждает наше предположение насчет door_revoke. Второй вызов возвращает ошибку EBADF.

9. Чтобы не делать дескриптор fd глобальным, мы воспользуемся указателем cookiе, который можем передать door_create и который затем будет передаваться процедуре сервера при каждом вызове. В листинге Г.10 приведен текст сервера.

Листинг Г.10. Использование указателя cookie для избавления от глобальных переменных

//doors/server9.c

1  #include "unpipc.h"


2  void

3  servproc(void *cookie, char *dataptr, size_t datasize,

4   door_desc_t *descptr, size_t ndesc)

5  {

6   long arg, result;

7   Door_revoke(*((int *) cookie));

8   arg = *((long *) dataptr);

9   printf("thread id %ld, arg = %ldn", pr_thread_id(NULL), arg);

10  result = arg * arg;

11  Door_return((char *) &result, sizeof(result), NULL, 0);

12 }


13 int

14 main(int argc, char **argv)

15 {

16  int fd;

17  if (argc != 2)

18   err_quit("usage: server9 <server-pathname>");

19  fd = Door_create(servproc, &fd, 0);

20  unlink(argv[1]);

21  Close(Open(argv[1], O_CREAT | O_RDWR, FILE MODE));

22  Fattach(fd, argv[1]);

23  for(;;)

24   pause();

25 }

Мы легко могли бы изменить листинги 5.17 и 5.18, поскольку указатель cookie доступен функции my_thread (через структуру door_info_t), которая передает указатель на эту структуру создаваемому потоку (которому нужно знать дескриптор для вызова door_bind).

10. В этом примере атрибуты потока не меняются, поэтому их достаточно инициализировать лишь единожды (в функции main).

Глава 16

1. Программа отображения портов (port mapper) не проверяет серверы на работоспособность во время регистрации. После завершения сервера отображения остаются в силе, в чем мы можем убедиться с помощью пpoгрaммы rpcinfо. Поэтому клиент, связывающийся с программой отображения портов, получит информацию, которая была актуальной до завершения сервера. Когда клиент попытается связаться с сервером по TCP, библиотека RPC получит RST в ответ на пакет SYN (предполагается, что другие процессы не успели подключиться к порту завершенного сервера), что приведет к возврату ошибки функцией clnt_create. Вызов по протоколу UDP будет успешен (поскольку устанавливать соединение не нужно), но при отправке дейтаграмм через устаревший порт ответ получен не будет и функция клиента выйдет по тайм-ауту.

2. Библиотека RPC возвращает первый ответ сервера клиенту сразу по получении, то есть через 20 секунд после вызова клиента. Следующий ответ будет храниться в сетевом буфере для данной конечной точки до тех пор, пока эта точка не будет закрыта или не будет выполнена операция чтения из нее библиотекой RPC. Предположим, что клиент отправит второй вызов серверу сразу после получения первого ответа. Если потерь в сети не произойдет, следующей прибывшей дeйтaгрaммoй будет ответ сервера на повторно переданную клиентом дейтаграмму. Но библиотека RPC проигнорирует этот ответ, поскольку XID будет совпадать с первым вызовом процедуры, который не может быть равным XID для второго вызова.

3. Соответствующая структура в С — это char c[10], но она будет закодирована XDR как десять 4-байтовых целых. Если вы хотите использовать строку фиксированной длины, используйте скрытый тип данных фиксированной длины.


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

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


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

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

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