Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
48
В действительности это хорошо работает и на файловой системе ext2. Эти две файловые системы очень похожи (можно даже смонтировать систему ext3 на ext2), и представленные программы работают на обеих. Фактически, если в исходных тексте заменить 3 на 2, программы будут функционировать точно так же.
49
Хотя не гарантировано, что PATH_MAX будет достаточно велик, но для большинства практических целей она подходит. Если вы имеете дело с патологическими случаями, то должны вызывать readlink() последовательно, увеличивая буфер, до тех пор, пока readlink() не вернет значение меньше чем bufsiz.
50
В зависимости от операционной системы, файловые структуры также известны как позиции в таблице файлов или объекты открытых файлов.
51
Файловый дескриптор в каждом процессе ссылается на одну и ту же файловую структуру.
52
Эта терминология распространена в большей части литературы по стандартам, включая единую спецификацию Unix (Single Unix Specification).
53
Это механизм, используемый для утилиты nohup.
54
Необходимость в реентерабельных функциях не ограничивается обработчиками сигналов. Многопоточные приложения должны с большой осторожностью относиться к обеспечению реентерабельности и блокировкам.
55
Вообще-то, не совсем так. Модель обработки сигналов ANSI/ISO С специфицирована немного иначе, чем мы ее представили. Однако она допускает сброс обработчика в значение SIG_DFL перед доставкой сигнала, что делает функции signal() в ASNI/ISO С ненадежными.
56
Спецификация POSIX Real Time Signal позволяет некоторые сигналам ставить в очередь, и для сигналов, работающих с ограниченными объемами данных, существенно изменяет эту модель. Сигналы реального времени обсуждаются ближе к концу этой главы.
57
Это аналогично типу fd_set, который используется системным вызовом select(), описанным в главе 13.
58
Разница между быстрыми и медленными файлами та же, что и между быстрыми и медленными системными вызовами, и она обсуждается в главе 11.
59
Имеются и другие отличия между этими вызовами; они касаются многопоточных программ, которые в настоящей книге не рассматриваются.
60
В действительности она отправляет сигнал текущему потоку текущего процесса.
61
Эти флаги определены в Single Unix Specification. Многие из них имеют имена, отличающиеся от описанных в тексте.
62
Хотя ссылка на память, которая может быть заполнена, может работать в некоторых системах, это не является переносимым. Некоторые реализации malloc() возвращают память операционной системе, что при обращении к возвращенной памяти вызывает ошибку сегментации; другие — перезаписывают части заполненной памяти служебной информацией.
63
Применение sigprocmask() и pause() для получения требуемого поведения может вызвать состояние состязаний, если сигнал, появление которого ожидается, поступит между этими двумя системными вызовами.
64
Более подробно о дампах памяти рассказывается в главе 10.
65
Хотя пользователи могут посылать SIGCHLD любым процессам, которыми они владеют, программы не обладают возможностью должным образом реагировать на непредвиденные сигналы.
66
В табл. 12.2 перечислены функции, которые могут отсутствовать в некоторых, а может, даже во всех системах Linux. Мы включаем все функции, которые POSIX специфицирует в качестве безопасных для вызова из обработчиков сигналов.
67
Термин реальное время употребляется здесь неправильно, поскольку это расширение не делает попыток обеспечить гарантии времени задержки при доставке сигнала. Однако средства, которые оно добавляет, удобны для построения реализаций систем реального времени.
68
До появления стандарта POSIX приложение могло обращаться к struct sigcontext за информацией того же рода, что теперь представляет siginfo_t, и термин "контекст" остался от этой старой реализации.
69
Этот третий параметр на самом деле указывает на структуру struct ucontext, которая позволяет процессам выполнять полное переключение контекстов в пользовательском пространстве. Данные вопросы выходят за пределы тем, рассматриваемых в настоящей книге, но это хорошо документировано в Single Unix Specification.
70
Существует гораздо больше значений si_code, нежели мы обсуждаем здесь, и эти значения имеют отношение к асинхронному вводу-выводу, очередям сообщений и таймерам реального времени, что выходит за границы тем, обсуждаемых в книге.
71
Он также принимает специальное значение SIGTRAP, которое используется отладчиками, и SIGPOLL, применяемое механизмом ненадежного асинхронного ввода-вывода. Ни один из них не описан в настоящей книге, поэтому подробности об этих сигналах не включены в табл. 12.3.
72
Вспомните, что SIGCHLD посылается не только при завершении дочернего процесса, но и при его приостановке или возобновлении работы.
73
Дополнительные примеры обработки сигналов вы можете найти в программах для аренды файлов (глава 13), управления терминалом (глава 16) и работы с интервальными таймерами (глава 18).
74
Это похоже на тип sigset_t, используемый для шаблонов сигналов.
75
Когда сетевой сокет прослушивается (listen()) и готов к приему (accept()), считается, что он готов к считыванию для целей select(); информацию о сокетах можно найти в главе 17.
76
Если сравнить это с параметром numfds для poll(), то можно понять, почему возникают затруднения.
77
Кроме некоторых экспериментальных ядер серии 2.1.
78
Когда Линус Торвальдс впервые реализовал select(), неспособность ядра BSD обновлять timeout была отмечена как ошибка на man-странице для select(). Вместо написания ошибочного кода Линус решил "исправить" эту ошибку. К сожалению, комитеты по стандартам одобрили поведение BSD.
79
Фактически ядро устанавливает обратный вызов для каждого файла, а затем, когда происходит событие, активизирует обратный вызов. Этот механизм устраняет проблемы масштабируемости при очень большом количестве файловых дескрипторов, поскольку опрос не используется в каждой точке.
80
EPOLLET — это еще одно значение, которое может иметь events, переключающее epoll с запуска уровнем на запуск фронтом сигнала. Эта тема выходит за рамки настоящей книги, и epoll, запускаемую фронтом, следует применять только в особых случаях.
81
Структура, показанная в тексте, предоставляет правильные размеры элементов на большинстве платформ, но они неправильны для машин, в которых int имеет 64 бита.
82
Эту программу необходимо запускать от имени root для наборов, содержащих более 1000 дескрипторов.
83
Настоящее тестирование не гарантирует статистическую точность. Был проведен лишь один тестовый прогон, поэтому результаты поначалу будут неустойчивыми, что, однако, исчезнет после большого количества повторов.
84
Сохранение копии памяти может показаться не столь важным, но благодаря эффективному механизму кэширования Linux, эти задержки копий являются самой медленной частью записи в файлы данных, в которых нет набора O_SYNC.
85
Хотя большинство устройств символьного ввода-вывода не могут быть отображены, /dev/zero отображается именно для этого типа приложений.
86
Ошибка сегментации возникнет при попытке доступа к нераспределенной странице.
87
В будущем это может измениться, поскольку в ядре реализуются мелкомодульные системные полномочия.
88
Файл /etc/passwd обновляется только процессами, создающими новую копию файла с модификациями и затем заменяющими оригинал с помощью системного вызова rename(). Поскольку такая последовательность является атомарной, процессы могут считывать из etc/passwd в любое время.