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

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

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

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

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

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

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

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

8. В листинге Г.3 приведен текст соответствующей программы.

Листинг Г.З. Возвращает ли fstat количество байтов в канале FIFO?

//pipe/test1l.c

1  #include "unpipc.h"


2  int

3  main(int argc, char **argv)

4  {

5   int fd[2],

6   char buff[7];

7   struct stat info;

8   if (argc != 2)

9    err_quit("usage: test1 <pathname>");

10  Mkfifo(argv[1], FILE_MODE);

11  fd[0] = Open(argv[1], O_RDONLY | O_NONBLOCK);

12  fd[1] = Open(argv[1], O_WRONLY | O_NONBLOCK);

13  /* 4check sizes when FIFO is empty */

14  Fstat(fd[0], &info);

15  printf("fd[0]: st_size = %ldn", (long) info.st_size);

16  Fstat(fd[1], &info);

17  printf("fd[1]: st_size = %ldn", (long) info.st_size);

18  Write(fd[1], buff, sizeof(buff));

19  Fstat(fd[0], &info);

20  printf("fd[0]: st_size = %ldn", (long) info.st_size);

21  Fstat(fd[1], &info);

22  printf("fd[1]: st_size = %ldn", (long) info.st_size);

23  exit(0);

24 }

9. Вызов select возвращает информацию о возможности записи в дескриптор, но вызов write приводит к отправке сигнала SIGPIPE. Это описано в книге [24, с. 153-155]; когда возникает ошибка чтения или записи, select возвращает информацию о том, что дескриптор доступен, а собственно ошибка возвращается уже вызовами read или write. В листинге Г.4 приведен текст соответствующей пpoгрaммы.

Листинг Г.4. Что возвращает select при закрытии другого конца канала?

//pipe/test2.c

1  #include "unpipc.h"


2  int

3  main(int argc, char **argv)

4  {

5   int fd[2], n;

6   pid_t childpid;

7   fd_set wset;

8   Pipe(fd);

9   if ((childpid = Fork()) == 0) { /* child */

10   printf("child closing pipe read descriptorn");

11   Close(fd[0]);

12   sleep(6);

13   exit(0);

14  }

15  /* 4parent */

16  Close(fd[0]); /* для двустороннего канала */

17  sleep(3);

18  FD_ZERO(&wset);

19  FD_SET(fd[1], &wset);

20  n = select(fd[1] + 1, NULL, &wset, NULL, NULL);

21  printf("select returned %dn", n);

22  if (FD_ISSET(fd[1], &wset)) {

23   printf("fd[1] writablen");

24   Write(fd[1], "hello", 5);

25  }

26  exit(0);

27 }

Глава 5

1. Сначала создайте очередь, не указывая никаких атрибутов, а затем вызовите mq_getattr для получения атрибутов по умолчанию. Затем удалите очередь и создайте ее снова, используя значения по умолчанию для всех неуказанных атрибутов.

2. Для второго сообщения сигнал не отправляется, поскольку регистрация снимается после отправки первого сигнала.

3. Для второго сообщения сигнал не отправляется, поскольку в момент отправки этого сообщения очередь не была пуста.

4. Компилятор GNU С в системе Solaris 2.6 (в котором обе константы определены как вызовы sysconf) возвращает ошибки:

test1.c:13: warning: int format, long int arg (arg 2)

test1.c:13: warning: int format, long int arg (arg 3)

5. В Solaris 2.6 мы указываем 1000000 сообщений по 10 байт в каждом. При этом создается файл размером 20000536 байт, что соответствует результатам, полученным с помощью пpoгрaммы 5.4: 10 байт данных на сообщение, 8 байт дополнительной информации (возможно, указатели), еще 2 байта добавочной информации (возможно, дополнение до кратного 4) и 536 байт добавочных данных на весь файл. Перед вызовом mq_open размер программы, выводимый ps, равнялся 1052 Кбайт, а после создания очереди размер вырос до 20 Мбайт. Это заставляет предположить, что очереди сообщений Posix реализованы через отображение файлов в память, и mq_open отображает файл в адресное пространство вызвавшего процесса. Аналогичные результаты получаются в Digital Unix 4.0B.

6. Размер аргумента, равный нулю, не вызывает проблем с функциями ANSI С memXXX. В оригинале стандарта 1989 года Х3.159-1989 (ISO/IEC 9899:1990) ничего не говорилось по этому поводу (как и в документации), но в Technical Corrigendum Number 1 явно говорится, что указание размера 0 не вызовет проблем (но аргументы и указатели при этом должны быть правильными). Вообще, за информацией по языку С лучше всего обращаться по адресу http://www.lysator.liu.se/c/.

7. Для двустороннего взаимодействия процессов требуется наличие двух очередей сообщений (см. например, листинг А.15). Если бы мы изменили листинг 4.4 для использования очередей сообщений Posix вместо каналов, мы бы увидели, что родительский процесс считывает то, что сам же и отправил.

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

9. Массиву нельзя присвоить значение другого массива с помощью знака равенства в языке С, а вот структуре можно.

10. Функция main проводит большую часть времени заблокированной в вызове select, ожидая возможности чтения из конца канала. Каждый раз при получении сигнала возврат из обработчика прерывает вызов select, что приводит к возврату ошибки EINTR. Чтобы избежать этой проблемы, функция-обертка Select проверяет возврат данного кода ошибки и снова вызывает select, как показано в листинге Г.5. В книге [24, с. 124] вы можете найти более подробный рассказ о прерывании системных вызовов.

Листинг Г.5. Обертка Select, обрабатывающая возврат EINTR

//lib/wrapunix.c

313 int

314 Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,

315  struct timeval *timeout)

316 {

317  int n;

318 again:

319  if ( (n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0) {

320   if (errno == EINTR)

321    goto again;

322  else

323   err_sys("select error");

324  } else if (n == 0 && timeout == NULL)

325   err_quit("select returned 0 with no timeout");

326  return(n); /* возвращаем 0 по тайм-ауту */

327 }

Глава 6

1. Оставшиеся программы должны принимать идентификатор очереди в числовом виде (вместо полного имени). Это изменение можно осуществить путем добавления нового аргумента командной строки или с помощью предположения, что полное имя, состоящее из одних цифр, является не именем файла, а идентификатором очереди. Поскольку большинство имен файлов, передаваемых ftok, являются абсолютными, они заведомо содержат по крайней мере один нецифровой символ (слэш), и это предположение является вполне корректным.

2. Передача сообщений с типом 0 запрещена, а клиент никогда не может иметь идентификатор 1, поскольку этот идентификатор обычно принадлежит процессу init.

3. При использовании единственной очереди на рис. 6.2 злоумышленник мог повлиять на все прочие процессы-клиенты. Если у каждого клиента есть своя очередь (рис. 6.3), злоумышленник портит только свою.

Глава 7

2. Вероятно, процесс завершит работу, прежде чем потребитель успеет сделать все, что нужно, поскольку вызов exit завершает все выполняющиеся потоки.

3. В Solaris 2.6 удаление вызова функций типа destroy приводит к утечке памяти, из чего становится ясно, что функции init осуществляют динамическое выделение памяти. В Digital Unix 4.0B такого не наблюдается, что указывает на разницу в реализации. Тем не менее вызывать функции destroy все равно нужно. С точки зрения реализации в Digital Unix 4.0B используется переменная типа attr_t как объект, содержащий атрибуты, а в Solaris 2.6 эта переменная представляет собой указатель на динамически создаваемый объект.

Глава 9

1. В зависимости от системы может потребоваться увеличивать счетчик до значений, больших 20, чтобы наблюдать ошибку.

2. Для отключения буферизации стандартного потока мы добавляем строку

setvbuf(stdout, NULL, _IONBF, 0);

к функции main перед циклом for. Это не должно ни на что влиять, поскольку вызов printf только один и строка завершается символом перевода. Обычно стандартный поток вывода буферизуется построчно, поэтому в любом случае один вызов printf превращается в один системный вызов write.

3. Заменим printf на

snprintf(line, sizeof(line), "%s: pid = 3.1d, seq# = %dn", argv[0], (long) pid, seqno);

for (ptr = line; (c = *ptr++) != 0) putchar(c);

и объявим с как целое, a ptr — как char*. Если мы вызвали setvbuf для отключения буферизации стандартного потока вывода, библиотека будет делать системный вызов для вывода каждого символа. На это требуется больше времени, что дает ядру больше возможностей на переключение контекста между процессами. Такая программа должна давать больше ошибок.

4. Поскольку несколько процессов могут заблокировать на чтение одну и ту же область файла, в нашем примере это эквивалентно полному отсутствию блокировок.

5. Ничего не изменится, поскольку флаг отключения блокировки для дескриптора никак не влияет на работу рекомендательной блокировки fcntl. Блокирование процесса при вызове fcntl определяется типом команды: F_SETLKW (которая блокируется всегда) или F_SETLK (которая не блокируется никогда).


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

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


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

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

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