Неблокирующий ввод/вывод для каналов и FIFO — КиберПедия 

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Неблокирующий ввод/вывод для каналов и FIFO

2021-01-29 93
Неблокирующий ввод/вывод для каналов и FIFO 0.00 из 5.00 0 оценок
Заказать работу

 

Ранее для описания способа работы каналов мы использовали сравнение с двумя людьми, моющими и вытирающими тарелки с использованием сушилки; когда сушилка заполняется, останавливается моющий, а когда она пустеет, останавливается вытирающий. Это блокирующее поведение: производитель или потребитель блокируются в вызове или, ожидая либо освобождения канала, либо появления в нем данных.

В действительности человек, ожидающий опустения или заполнения сушилки, не должен просто неподвижно стоять.[101] Вместо этого незанятый супруг мог бы пойти и найти другую работу по кухне (такую, как подметание всех крошек за детьми на полу), пока сушилка снова не будет готова.

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

С функцией может использоваться флаг для указания неблокирующего ввода/вывода, он может быть установлен и сброшен с помощью. Для и неблокирующий ввод/вывод прост.

Открытие FIFO с установленным или сброшенным демонстрирует следующее поведение:

 

Блокируется до открытия FIFO для записи.

 

Открывает файл, возвращаясь немедленно.

 

Блокирует до открытия FIFO для чтения.

 

Если FIFO был открыт для чтения, открывает FIFO и немедленно возвращается. В противном случае возвращает ошибку (возвращаемое значение ‑1 и установлен в).

Как описано для обычных каналов, вызов для FIFO, который больше не открыт для чтения, возвращает конец файла (возвращаемое значение 0). Флаг в данном случае неуместен. Для пустого канала или FIFO (все еще открытых для записи, но не содержащих данных) все становится интереснее:

 

Функция блокируется до тех пор, пока в канал или FIFO не поступят данные.

 

Функция немедленно возвращает ‑1 с установленным в.

В заключение, поведение более сложно. Для обсуждения этого нам нужно сначала представить концепцию атомарной записи. Атомарная запись – это такая запись, при которой все данные записываются целиком, не чередуясь с данными от других записей. POSIX определяет в константу. Запись в канал или FIFO данных размером менее или равным байтов либо успешно завершается, либо блокируется в соответствии с подробностями, которые мы скоро приведем. Минимальным значением для является, что равняется 512. Само значение может быть больше; современные системы GLIBC определяют ее размер в 4096, но в любом случае следует использовать эту именованную константу и не ожидать, что будет иметь то же значение на разных системах.

Во всех случаях для каналов и FIFO добавляет данные в конец канала. Это происходит от того факта, что у каналов нет файловых смещений: в них нельзя осуществлять поиск.

Также во всех случаях, как упоминалось, записи размером вплоть до являются атомарными: данные не перемежаются с данными от других записей. Данные записи размером более байтов могут перемежаться с данными других записей в произвольных границах. Это последнее означает, что вы не можете ожидать, что каждая порция размером большого набора данных будет записана атомарно. Установка не влияет на это правило.

Как и в случае с, когда не установлен, блокируется до тех пор, пока все данные не будут записаны.

Наиболее все усложняется, когда установлен. Канал или FIFO ведут себя следующим образом:

 

  размер ≥ nbytes размер < abytes
   успешна  возвращает
  размер > 0 размер = 0
   записывает, что может  возвращает

Для файлов, не являющихся каналами и FIFO и к которым может быть применен, поведение следующее:

размер > 0 записывает, что может

размер = 0 возвращает

Хотя есть ряд сбивающих с толку изменений поведения в зависимости от того, канал это или не канал, установлен или сброшен, есть в канале место для записи или нет, а также в зависимости от размера предполагаемой записи, эти правила предназначены для упрощения программирования:

• Всегда можно отличить конец файла: возвращает 0 байтов.

• Если нет доступных для чтения данных, либо завершается успешно, либо возвращает указание «нет данных для чтения»:, что означает «попытайтесь снова позже».

• Если для записи нет места, либо блокируется до успешного завершения (сброшен), либо завершается неудачей с ошибкой «в данный момент нет места для записи»:.

• Когда место есть, будет записано столько данных, сколько возможно, так что в конечном счете все данные будут переписаны.

Подводя итог, если вы собираетесь использовать неблокирующий ввод/вывод, любой код, который использует, должен быть способен обработать укороченную запись, когда успешно записан меньший объем данных, чем было затребовано. Устойчивый код в любом случае должен быть написан таким способом: даже в случае обычного файла диск может оказаться заполненным и сможет записать лишь часть данных.

Более того, вы должны быть готовы обработать, понимая, что в этом случае неудача не обязательно означает фатальную ошибку. То же верно для кода, использующего для чтения неблокирующий ввод/вывод: признайте, что и здесь не является фатальным. (Однако, может стоит подсчитывать число таких отказов, оставив попытки, когда их слишком много.)

Неблокирующий ввод/вывод действительно усложняет вашу жизнь, в этом нет никакого сомнения. Но для многих приложений он является необходимостью, позволяющей выполнить задание. Снова рассмотрите спулер печати. Демон спулера не может позволить себе находиться в блокирующем для файла FIFO, которому представлены входящие задания. Он должен иметь также возможность отслеживать запущенные задания и, возможно, периодически проверять состояние печатающих устройств (например, убедиться, что не заело бумагу).

 

Сводка fcntl()

 

Сводка для системного вызова приведена в табл. 9.5.

 

Таблица 9.5. Сводка

 

 Значение Значение Возвращает
  Наименьший новый дескриптор Дублирует аргумент
    Получает флаги дескриптора файла (close‑on‑exec)
  Новое значение флага Устанавливает флаги дескриптора файла (close‑on‑exec)
    Получает флаги основного файла
  Новое значение флага Устанавливает флаги основного файла

Флаги создания, статуса и прав доступа файла копируются, когда дескриптор файла дублируется. Флаг close‑on‑exec не копируется.

 

Пример: двусторонние каналы в

 

Двусторонний канал соединяет два процесса двунаправленным образом. Обычно, по крайней мере для одного из процессов, на канал с другим процессом настраиваются как стандартный ввод, так и стандартный вывод. Оболочка Корна () ввела двусторонние каналы на уровне языка, обозначив термином сопроцесса (coprocess):

команды и аргументы движка базы данных

 

 

Здесь движок базы данных представляет любую серверную программу, которая может управляться интерфейсной частью, в данном случае, сценарием. У движка базы данных стандартный ввод и стандартный вывод подсоединены к оболочке посредством двух отдельных односторонних каналов.[102] Это показано на рис. 9.7.

Рис. 9.7. Сопроцессы оболочки Корна

В обычном каналы к или от подпроцесса являются односторонними: нет способа послать данные в программу и прочесть посланные от нее в ответ данные – нужно использовать временный файл. GNU () заимствует обозначение '' от для расширения языка:

команда движок базы данных

движок базы данных

 использует запись '' также для сокетов TCP/IP и порталов BSD, которые не рассматриваются в данной книге. Следующий код из в дистрибутиве 3.1.3 является частью функции, которая устанавливает простой сопроцесс: она создает два канала, порождает новый процесс и осуществляет все манипуляции с дескриптором файла. Мы опустили ряд не относящихся к делу частей кода (эта функция занимает больше места, чем следовало бы):

 

Первым шагом является создание двух каналов, является каналом «от родителя к потомку», а – «от потомка к родителю». Во время чтения держите в уме, что индекс 0 является читаемым концом, а 1 – записываемым.

Строки 1836–1837 создают первый канал,. Строки 1839–1845 создают второй канал, закрывая при неудачном создании и первый. Это важно. Небрежность в закрытии открытых, но не используемых каналов ведет к утечкам дескрипторов файлов. Как и память, дескрипторы файлов являются конечным ресурсом, и когда они иссякают, то теряются.[103] То же верно и для открытых файлов: убедитесь, что ваш обрабатывающий ошибки код всегда закрывает все открытые файлы и каналы, которые не нужны, когда происходит ошибка.

 сохраняет значения, установленные, на тот редкий случай, когда может завершиться неудачей (строка 1840). Затем восстанавливается в строке 1843.

 

Строки 1906–1912 порождают процесс, на этот раз закрывая оба канала, если потерпит неудачу. Здесь также первоначальное значение сохраняется и восстанавливается для последующего использования при диагностике.

 

 

Строки 1914–1931 обрабатывают код потомка, с соответствующей проверкой ошибок и сообщениями на каждом шагу. Строка 1915 закрывает стандартный вывод. Строка 1918 копирует записываемый конец канала от потомка к родителю на 1. Строка 1920 закрывает стандартный ввод, а строка 1923 копирует читаемый конец канала от родителя к потомку на 0. Если это все работает, стандартные ввод и вывод теперь на месте и подключены к родителю.

Строки 1925–1926 закрывают все четыре первоначальные дескрипторы файлов каналов, поскольку они больше не нужны. Строка 1928 напоминает нам, что стандартная ошибка остается на месте. Это лучшее решение, поскольку пользователь увидит ошибки от сопроцесса. Программа, которая должна перехватить стандартную ошибку, может использовать в команде обозначение '' для перенаправления стандартной ошибки сопроцесса или записи в отдельный файл.

Наконец, строки 1929–1930 пытаются запустить для оболочки и соответственно выходят, если это не удается.

 

 

Первым шагом родителя является настройка входного конца от сопроцесса. Указатель указывает на, которая содержит поле для сохранения PID порожденного процесса, для вывода и указатель с именем. является внутренней структурой данных для осуществления ввода. Она, в свою очередь, хранит копию нижележащего дескриптора файла.

Строка 1935 сохраняет значение ID процесса. Строка 1936 выделяет память для новой для данных дескриптора файла и командной строки. Третий аргумент здесь равен: он позволяет при необходимости использовать предварительно выделенный.

Если выделение памяти потерпело неудачу, строки 1937–1942 производят очистку, закрывая каналы и посылая сигнал «kill» порожденным процессам, чтобы заставить их завершить работу. (Функция описана в разделе 10.6.7 «Отправка сигналов и».)

 

 

[104] 

 

Строки 1946–1957 аналогичны. Они устанавливают вывод родителя на потомка, сохраняя дескриптор файла для записывающего конца канала от родителя к потомку в, используя функцию. Если это завершается неудачей, строки 1947–1957 предпринимают те же действия, что и ранее: закрывают все дескрипторы каналов и посылают сигнал порожденным процессам.

С этого момента записываемый конец канала от родителя к потомку и читаемый конец канала от потомка к родителю хранятся в более крупных структурах: и соответственно. Они автоматически закрываются обычными процедурами, которые закрывают эти структуры. Однако, остаются две задачи:

 

 

Строки 1960–1961 устанавливают флаг close‑on‑exec для двух дескрипторов, которые остались открытыми. является простой функцией‑оболочкой, которая выполняет эту работу на Unix‑ и POSIX‑совместимых системах, но ничего не делает на системах, в которых нет флага close‑on‑exec. Это скрывает проблему переносимости в одном месте и позволяет избежать в коде множества запутывающих здесь и в других местах.

Наконец, строки 1963–1964 закрывают концы каналов, которые не нужны родителю, а строка 1967 возвращает TRUE для обозначения успеха.

 

9.6. Рекомендуемая литература

 

Управление заданиями сложно, включает группы процессов, сеансы, механизмы ожидания, сигналы и манипулирование группой процессов терминала. По существу, мы решили не вдаваться в детали. Однако, вы можете захотеть взглянуть на следующие книги:

1. Advanced Programming in the UNIX Environment, 2nd edition, by W. Richard Stevens and Stephen Rago. Addison‑Wesley, Reading Massachusetts, USA, 2004. ISBN: 0‑201‑43307‑9.

Эта книга и полна, и основательна, охватывая элементарное и продвинутое программирование под Unix. Она превосходно освещает группы процессов, сеансы, управление заданиями и сигналы

2. The Design and Implementation of the 4.4 BSD Operating System, by Marshall Kirk McKusick, Keith Bostic, Michael J. Karels, and John S. Quarterman. Addison‑Wesley, Reading, Massachusetts, USA, 1996. ISBN: 0‑201‑54979‑4.

Эта книга дает хороший обзор того же материала, включая обсуждение структур данных ядра, которое можно найти в разделе 4.8 этой книги.

 

Резюме

 

• Новые процессы создаются с помощью. После этого оба процесса исполняют один и тот же код, причем единственным различием является возвращаемое значение: 0 в порожденном процессе и положительный номер PID в родительском. Порожденный процесс наследует копии почти всех атрибутов родителя, наиболее важными из которых являются, пожалуй, открытые файлы.

• Унаследованные разделяемые дескрипторы файлов делают возможным многое из высокоуровневой семантики Unix и элегантные управляющие структуры оболочки. Это одна из наиболее фундаментальных частей оригинального дизайна Unix. Из‑за разделения дескрипторов файл на самом деле не закрывается до тех пор, пока не будет закрыт последний открытый дескриптор файла. Это в особенности касается каналов, но затрагивает также освобождение дисковых блоков для удаленных, но все еще открытых файлов.

• Вызовы и возвращают ID текущего и родительского процессов соответственно. Родителем процесса, первоначальный родитель которого завершается, становится специальный процесс с PID 1. Таким образом, PPID может меняться, и приложения должны быть готовы к этому.

• Системный вызов дает возможность настраивать приоритет вашего процесса. Чем приятнее вы по отношению к другим процессам, тем меньше ваш относительный приоритет, и наоборот. Лишь суперпользователь может иметь больший приоритет по сравнению с другими процессами. На современных системах, особенно однопользовательских, нет действительных причин для изменения знамения относительного приоритета.

• Системный вызов начинает исполнение новой программы в существующем процессе. Шесть различных версий вызова предоставляют гибкость в установке списков аргументов и окружения ценой первоначальной путаницы по поводу того, какую из них лучше всего использовать. Два варианта имитируют механизм поиска оболочки и отступают к использованию оболочки для интерпретации файла в случае, если он не является двоичным исполняемым файлом; эти варианты должны использоваться с предусмотрительностью.

• Значение для новой программы обычно происходит от имени исполняемого файла, но это лишь соглашение. Как и в случае с, значительный, но не идентичный набор атрибутов наследуется через. Другие атрибуты сбрасываются для использования подходящих значений по умолчанию.

• Функция регистрирует функции обратного вызова для вызова в порядке LIFO при завершении программы. Функции, и все завершают программу, передавая статус завершения обратно родителю, очищает открытые потоки и запускает функции, зарегистрированные с помощью. Две другие функции завершаются немедленно и должны использоваться, лишь когда в порожденном процессе завершилась неудачей. Возвращение из подобно вызову с данным возвращаемым значением. В C99 и C++ выпадение из в конце функции дает тот же результат, что и '', но является плохой практикой.

• и являются функциями POSIX для получения статуса завершения порожденного процесса. Различные макросы позволяют определить, завершился ли порожденный процесс нормально, и в таком случае определить статус его завершения, или же порожденный процесс претерпел сигнал завершения, и в этом случае определить совершивший этот проступок сигнал. Со специальными опциями предоставляет также сведения о потомках, которые не завершились, но изменили состояние.

• Системы GNU/Linux и большинство Unix‑систем поддерживают также функции BSD и. GNU/Linux поддерживает также выходящий из употребления. Функции BSD предоставляют, давая доступ к сведениям об использовании времени процессора, что может быть удобным. Хотя если будет достаточной, то это наиболее переносимый способ выполнения.

• Группы процессов являются частью более крупного механизма управления заданиями, который включает сигналы, сеансы и манипулирование состоянием терминала, возвращает ID группы процессов текущего процесса, a возвращает PGID определенного процесса. Сходным образом, устанавливает PGID текущего процесса равным его PID, делая его лидером группы процессов; дает возможность родительскому процессу установить PGID порожденного, который еще не выполнил.

• Каналы и FIFO предоставляют односторонний коммуникационный канал между двумя процессами. Каналы должны быть установлены общим предком, тогда как FIFO могут использоваться любыми двумя процессами. Каналы создаются с помощью, а файлы FIFO создаются с помощью. Каналы и FIFO буферируют свои данные, останавливая производителя или потребителя, когда канал заполняется или пустеет.

• и создают копии дескрипторов открытых файлов. В сочетании с они дают возможность поместить дескрипторы файлов на место стандартного ввода и вывода для каналов. Чтобы каналы работали правильно, все копии неиспользуемых концов каналов до исполнения программой назначения exec должны быть закрыты. Для создания нелинейных каналов может быть использован, что демонстрируется возможностью замещения процессов оболочками Bash и Korn.

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

• Дублирования дескриптора файла, имитирования и почти имитирования.

• Получения и установки флага close‑on‑exec. Флаг close‑on‑exec является в настоящее время единственным атрибутом дескриптора файла, но он важен. Он не копируется в результате действия, но должен явным образом устанавливаться для дескрипторов файлов, которые не должны оставаться открытыми после выполнения exec. На практике, это должно быть сделано для большинства дескрипторов файла.

• Получение и установка флагов, управляющих нижележащим файлом. Из них является, пожалуй, наиболее полезным, по крайней мере, для FIFO и каналов. Это определенно самый сложный флаг.

 

Упражнения

 

1. Напишите программу, которая выводит как можно больше сведений о текущем процессе: PID, PPID, открытые файлы, текущий каталог, значение относительного приоритета и т.д. Как вы можете сказать, какие файлы открыты? Если несколько дескрипторов файлов ссылаются на один и тот же файл, укажите это. (Опять‑таки, как вы можете это узнать?)

2. Как вы думаете, хранит указатели на функции обратного вызова? Реализуйте, держа в уме принцип GNU «никаких произвольных ограничений». Набросайте схему (псевдокод) для. Каких сведений (внутренностей библиотеки) вам не хватает, чтобы написать?

3. Программа предназначена для многократных запусков команды и аргументов, когда аргументов слишком много для непосредственного набора в командной строке. Программа работает, считывая строки из стандартного ввода, рассматривая каждую строку в качестве отдельного аргумента для указанной команды, и упаковывая аргументы до тех пор, пока они остаются в пределах максимально допустимого для системы. Например:

grep ARG_MAX /usr/include/*.h /usr/include/*/*.h

 

find /usr/include ‑name '*.h' | xargs grep ARG_MAX

 

 

Константа в представляет сочетание общей памяти, используемой средой, и аргументов командной строки. Стандарт POSIX не говорит, включает ли это массивы указателей или просто сами строки.

Напишите простую версию, которая работает указанным способом. Не забудьте об окружении при вычислении размера необходимого пространства. Убедитесь, что тщательно управляете памятью.

4. Компоновка значения status, заполняемого функциями и, стандартом POSIX не определяется. Хотя и историческое, это 16‑разрядное значение, которое выглядит, как показано на рис. 9.8.

Рис. 9.8. Компоновка значения status функции

• Ненулевое значение в битах 0–7 указывает на завершение по сигналу.

• Все единичные биты в поле сигнала указывает, что порожденный процесс остановлен. В этом случае биты 9‑15 содержат номер сигнала.

• Единичное значение бита 8 указывает завершение со снимком процесса.

• Если биты 0–7 равны нулю, процесс завершился нормально. В этом случае биты 9–15 являются статусом завершения.

Напишите с данными сведениями макросы POSIX и др.

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

6. Есть ли на вашей системе каталог? Если есть, как он реализован?

7. Напишите новую версию, которая порождает лишь один процесс. После порождения родитель должен поменять дескрипторы своих файлов и сам выполнить exec для одной из новых программ.

8. (Трудное) Как вы можете узнать, вызывал ли ваш процесс когда‑нибудь? Напишите программу, которая проверяет это и выводит сообщение с ответом да или нет. Можно ли обмануть вашу программу? Если да, как?

9. Есть ли на вашей системе каталог? Если да, доступ к какой информации о процессе он обеспечивает?

 

 

Глава 10

Сигналы

 

Данная глава освещает все подробности сигналов, важную, но сложную часть GNU/Linux API.

 

Введение

 

Сигнал является указанием, что случилось какое‑то событие, например, попытка сослаться на адрес памяти, который не является частью адресного пространства вашей программы, или когда пользователь нажимает CTRL‑C для выхода из программы (называется генерированием прерывания).

Программа может узнать лишь, что определенный сигнал был по крайней мере однажды. Обычно вы не можете сказать, случился ли один и тот же сигнал несколько раз. Вы можете отличить один сигнал от другого и управлять способом реагирования программы на различные сигналы.

Механизмы обработки сигналов развились с течением времени. Как бывает почти со всеми такими механизмами, стандартизованы и доступны как первоначальные, так и более новые API. Однако, из фундаментальных API обработка сигналов обнаруживает, возможно, самые широкие изменения; имеется множество возможностей обработки, чтобы преуспеть в использовании наиболее подходящего API. В результате, возможно, это самая трудная глава в книге. Мы сделаем всевозможное, чтобы сделать изложение более ясным, но если вы проработаете эту главу более тщательно, чем обычно, это поможет.

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

 

Действия сигналов

 

Каждый сигнал (вскоре мы представим полный список) имеет связанное с ним действие по умолчанию. POSIX обозначает это как диспозицию (disposition) сигнала. Это то действие, которое ядро осуществляет для процесса, когда поступает определенный сигнал. Действие по умолчанию варьирует:

Завершение

Процесс завершается.

Игнорирование

Сигнал игнорируется. Программа никогда не узнает, что что‑то случилось.

Снимок образа процесса

Процесс завершается, и ядро создает файл core (в текущем каталоге процесса), содержащий образ работавшей на момент поступления сигнала программы. Снимок процесса может впоследствии использоваться с отладчиком для исследования состояния программы (см. главу 15 «Отладка»).

По умолчанию системы GNU/Linux создают файлы с именем pid, где pid является ID завершаемого процесса. (Это можно изменить; см. sysctl (8).) Такое именование позволяет хранить в одном и том же каталоге несколько файлов, за счет использования большего дискового пространства.[105] Традиционные системы Unix называют файл, и это ваше дело сохранить какие‑нибудь файлы для последующего изучения, если есть шанс создания других таких же файлов в том же каталоге.

Остановка

Процесс останавливается. Впоследствии он может быть возобновлен. (Если вы использовали управление заданиями оболочки с помощью CTRL‑Z, и, вы понимаете остановку процесса.)

 

Стандартные сигналы С: и

 

Стандарт ISO С определяет первоначальный API управления сигналами V7 и новый API для посылки сигналов. Вы должны использовать их для программ, которым придется работать на не‑POSIX системах, или в случаях, когда предоставляемые ISO С API возможности являются достаточными.

 

Функция

 

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

Функция, которую вы предоставляете для распоряжения сигналом, называется обработчиком сигнала (или просто обработчиком), а установка ее в соответствующем месте осуществляет перехват (catch) сигнала.

Получив эти сведения, давайте перейдем к API. В заголовочном файле представлены определения макросов для поддерживаемых сигналов и объявления функций управления сигналами, предоставляемыми стандартом С:

 

Это объявление для функции signal() почти невозможно прочесть. Поэтому справочная страница GNU/Linux signal (2) определяет ее таким способом:

 

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

Функция принимает номер сигнала в качестве своего первого параметра, а указатель функции (новый обработчик) в качестве своего второго аргумента. Если последний не является указателем функции, он может быть лишь что означает «восстановить действие по умолчанию», либо, что означает «игнорировать сигнал».

 изменяет действие для и возвращает предыдущее действие. (Это дает вам возможность восстановить при желании предыдущее действие.) Возвращаемое значение может равняться также, что указывает на произошедшую ошибку. (Некоторые сигналы невозможно перехватить или игнорировать; предоставление для них обработчика сигнала или неверный создают эту ошибку.) В табл. 10.1 перечислены сигналы, доступные под GNU/Linux, их числовые значения, действия по умолчанию для каждого, формальный стандарт или современная операционная система, которые их определяют, и смысл каждого.

 

Таблица 10.1. Сигналы GNU/Linux

 

 Имя Значение По умолчанию Источник Смысл
  1 Term POSIX Отсоединение
  2 Term ISO C Прерывание
  3 Core POSIX Выход
  4 Core ISO C Недействительная инструкция
  5 Core POSIX Трассировочная ловушка
  6 Core ISO C Прекращение
  6 Core BSD Ловушка IOT
  7 Core BSD Ошибка шины
  8 Core ISO C Исключение с плавающей точкой
  9 Term POSIX Завершение, неблокируемый
  10 Term POSIX Сигнал 1 пользователя
  11 Core ISO C Нарушение сегмента
  12 Term POSIX Сигнал 2 пользователя
  13 Term POSIX Нарушенный канал
  14 Term POSIX Аварийные часы
  15 Term ISO C Завершение
  16 Term Linux Ошибка стека в процессоре (не используется)
  17 Ignr POSIX Изменение статуса порожденного процесса
  17 Ignr System V То же, что и SIGCHLD (для совместимости)
  18   POSIX Продолжить при остановке
  19 Stop POSIX Стоп, неблокируемый
  20 Stop POSIX Стоп от клавиатуры
  21 Slop POSIX Фоновое чтение от tty
  22 Stop POSIX Фоновая запись в tty
  23 Ignr BSD Срочный сигнал сокета
  24 Core BSD Превышение предела процессора
  25 Core BSD Превышение предела размера файла
  26 Term BSD Виртуальные аварийные часы
  27 Term BSD Профилирующие аварийные часы
  28 Ignr BSD Изменение размера окна
  29 Term BSD Возможен ввод/вывод
  29 Term System V Опрашиваемое событие, то же, что и SIGIO (для совместимости)
  30 Term System V Повторный запуск из‑за сбоя питания
  31 Core POSIX Неверный системный вызов

Обозначения: Core: Завершить процесс и создать снимок образа процесса Ignr: Игнорировать сигнал Stop: Остановить процесс. Term: Завершить процесс.

Более старые версии оболочки Борна () непосредственно связывали с номерами сигналов ловушки (traps), которые являются обработчиками сигналов на уровне оболочки. Таким образом, всесторонне образованному Unix‑программисту нужно было знать не только имена сигналов для использования в коде С, но также и соответствующие номера сигналов! POSIX требует, чтобы команда понимала символические имена сигналов (без префикса ''), поэтому этого больше не требуется. Однако (главным образом для лучшего разбирательства), мы предоставили эти номера в интересах полноты из‑за того, что однажды вам может понадобиться иметь дело со сценарием оболочки, созданным до POSIX, или с древним кодом на С, которые непосредственно используют номера сигналов.

 

ЗАМЕЧАНИЕ. Для некоторых более новых сигналов, от 16 и выше, соответствующие номера сигнала и их имена на различных платформах не обязательно совпадают! Проверьте заголовочные файлы и справочные страницы на своей системе. Табл. 10.1 верна для GNU/Linux

 

Некоторые системы определяют также и другие сигналы, такие, как, и. Справочная страница GNU/Linux signal (7) предоставляет полный список; если ваша программа должна обработать сигналы, не поддерживаемые GNU/Linux, это можно сделать с помощью:

 

За исключением, сигналы, перечисленные в табл. 10.1, широкодоступны и не нуждаются в заключении в.

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

Чтобы увидеть список поддерживаемых сигналов, вы можете использовать ''. На одной из наших систем GNU/Linux:

kill ‑l

 

 

Сигналы XXX являются сигналами реального времени, сложная тема, которую мы не будем рассматривать.

 


Поделиться с друзьями:

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

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



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.114 с.