Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

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# = %d\n", 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 (которая не блокируется никогда).

6. Пpoгрaммa loopfcntlnonb работает как положено, поскольку, как мы показали в предыдущем примере, флаг отключения блокировки никак не влияет на блокировку fcntl. Однако этот флаг влияет на работу loopnonenonb, которая не пользуется блокировкой. Как говорилось в разделе 9.5, неблокируемый вызов write или read для файла с включенной обязательной блокировкой приводит к возврату ошибки EAGAIN. Мы увидим одно из следующих сообщений:

read error: Resource temporarily unavailable

write error: Resource temporarily unavailable

и мы можем проверить, что это сообщение соответствует EAGAIN, выполнив

solaris % grep Resource /usr/include/sys/errno.h

#define EAGAIN 11 /* Resource temporarily unavailable */

7. В Solaris 2.6 обязательная блокировка увеличивает время работы на 16%, а время процессора — на 20%. Пользовательское время процессора остается прежним, поскольку проверка осуществляется в ядре, а не в процессе.

8. Блокировки выдаются процессам, а не потокам.

9. Если бы работала другая копия демона, а мы открыли бы файл с флагом O_TRUNC, это привело бы к удалению идентификатора процесса из файла. Мы не имеем права укорачивать файл, пока не убедимся, что данная копия является единственной.

10. Лучше использовать SEEK_SET. Проблема с SEEK_CUR заключается в том, что этот вариант зависит от текущего положения в файле, устанавливаемого 1 seek. Однако если мы вызываем 1 seek, а потом fcntl, мы делаем одну операцию в два вызова и существует вероятность, что другой процесс в промежутке между вызовами изменит текущий сдвиг вызовом lseek. Вспомните, что все потоки используют общие дескрипторы. Аналогично, если указать SEEK_END, другой процесс может дописать данные к файлу, прежде чем мы получим блокировку, и тогда она уже не будет распространяться на весь файл.

Глава 10

1. Вот результат работы в Solaris 2.6:

solaris % deadlock 100

prod: calling sem_wait(nempty) i=0 у производителя

prod: got sem_wait(nempty)

prod: calling sem_wait(mutex)

prod: got sem_wait(mutex), storing 0

prod: calling sem_wait(nempty) i=1 у производителя

prod: got sem_wait(nempty)

  • Читать дальше
  • 1
  • ...
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: