Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
28
Добавлен:
11.04.2015
Размер:
125.95 Кб
Скачать

НАЗВАНИЕ

wait3, wait4 - ожидает завершения работы процесса (стиль BSD)  

СИНТАКСИС

#include <sys/types.h>

#include <sys/time.h>

#include <sys/resource.h>

#include <sys/wait.h>

pid_t wait3(int *status, int options,

struct rusage *rusage);

pid_t wait4(pid_t pid, int *status, int options,

struct rusage *rusage);

 

ОПИСАНИЕ

Функция wait3 приостанавливает исполнение текущего процесса до того, как дочерний процесс завершит свою работу, или он не получит сигнал, прекращающий его работу, или не будет произведен вызов обработчика прерывания. Если дочерний процесс уже прекратил свою работу на момент вызова этой функции (такой процесс называется "зомби" ("zombie")), то функция немедленно возвращается. Все системные ресурсы, использованные дочерним процессом, будут освобождены. Функция wait4 приостанавливает исполнение текущего процесса до того, как свою работу завершит дочерний процесс с номером pid, или этот процесс не получит сигнал, прекращающий его работу, или не будет произведен вызов обработчика прерывания. Если дочерний процесс pid уже прекратил свою работу на момент вызова этой функции (такой процесс называется "зомби"), то функция немедленно возвращается. Все системные ресурсы, использованные дочерним процессом, будут освобождены. Значение параметра pid может быть следующим:

< -1 - ожидание любого дочернего процесса, идентификатор группы процессов которого равен абсолютному значению pid.

-1 - ожидание любого дочернего процесса; это эквивалентно вызову wait3.

0 - ожидание любого дочернего процесса, идентификатор группы процессов которого равен идентификатору группы процессов текущего процесса.

> 0 - ожидание дочернего процесса, идентификатор которого равен pid.

Параметр options состоит из комбинации следующих флагов:

WNOHANG

- немедленно вернуть управление вызывающему процессу, если нет дочерних процессов, попадающих под действие функции.

WUNTRACED

- вернуться, если существуют остановленные дочерние процессы, а их статус еще не получен.

Если status не равен NULL, то wait3 или wait4 сохранят в памяти информацию о процессе в виде структуры status.

Эта информация может быть обработана следующими макросами (эти макросы используют в качестве аргумента буфер stat (int) --- не указатель на буфер!):

WIFEXITED(status)

не равен 0, если дочерний процесс корректно завершил работу.

WEXITSTATUS(status)

возвращает 8 последних значащих битов кода возврата завершенного дочернего процесса, который можно задать в качестве параметра к функции exit() или в качестве параметра оператора return в функции main программы. Этот макрос работает только в том случае, если WIFEXITED возвратил не 0.

WIFSIGNALED(status)

возвращает TRUE, если дочерний процесс прекратил свою работу из-за того, что получил сигнал, который не был обработан.

WTERMSIG(status)

возвращает номер сигнала, вызвавшего прекращение работы дочернего процесса. Этот макрос работает только в том случае, если WIFSIGNALED возвратил не 0.

WIFSTOPPED(status)

возвращает TRUE, если дочерний процесс, использовавший return для возврата из функции, на настоящий момент остановлен; это возможно только в том случае, если функция была вызвана с флагом WUNTRACED.

WSTOPSIG(status)

возвращает номер сигнала, вызвавшего остановку дочернего процесса. Этот макрос работает только в том случае, если WIFSTOPPED возвратил не 0.

Если rusage не равен NULL, то в него будет записана структура struct rusage, заданная в <sys/resource.h>, заполненная соответствующей информацией. Для подробностей смотрите getrusage(2).  

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Идентификатор дочернего процесса, прекратившего свою работу, возвращает -1 при ошибке (в частности, если не существует завершивших свою работу процессов заданного вида) или 0, если был задан флаг WNOHANG, а такого дочернего процесса пока нет. В последних двух случаях в переменную errno заносится код ошибки.  

КОДЫ ОШИБОК

ECHILD

Нет дочерних процессов заданного вида, завершивших свою работу.

EINTR

Флаг WNOHANG не был установлен, и вызывающим процессом был получен неблокируемый сигнал или сигнал SIGCHLD.

 ЗАМЕЧАНИЯ

Использование <sys/time.h> сейчас уже не требуется, но улучшает портируемость. (В самом деле, <sys/resource.h> определяет структуру rusage с полями типа struct timeval определенными в <sys/time.h>.)

Прототип этих функций доступен только если определен _BSD_SOURCE (непосредственно, или неявно если компилирование производится с флагом -ansi или если не определен _POSIX_SOURCE).  

СООТВЕТСТВИЕ СТАНДАРТАМ

SVr4, POSIX.1  

ИМЯ

wait, waitpid - ожидает завершения процесса  

КРАТКАЯ СВОДКА

#include <sys/types.h> #include <sys/wait.h>

pid_t wait(int *status) pid_t waitpid(pid_t pid, int *status, int options);  

ОПИСАНИЕ

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

Функция waitpid приостанавливает выполнение текущего процесса до тех пор, пока дочерний процесс, указанный в параметре pid, не завершит выполнение, или пока не появится сигнал, который либо завершает текущий процесс либо требует вызвать функцию-обработчик. Если указанный дочерний процесс к моменту вызова функции уже завершился (так называемый "зомби"), то функция немедленно возвращается. Системные ресурсы, связанные с дочерним процессом, освобождаются.

Параметр pid может принимать несколько значений:

< -1

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

-1

означает ожидать любого дочернего процесса; функция wait ведет себя точно так же.

0

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

> 0

означает ожидать дочернего процесса, чем идентификатор равен pid.

Значение options создается путем битовой операции ИЛИ над следующими константами:

WNOHANG

означает вернуть управление немедленно, если ни один дочерний процесс не завершил выполнение.

WUNTRACED

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

Если status не равен NULL, то функции wait и waitpid сохраняют информацию о статусе в переменной, на которую указывает status.

Этот статус можно исследовать с помощью нижеследующих макросов (они принимают в качестве аргумента буфер (типа int), --- а не указатель на буфер!):

WIFEXITED(status)

не равно нулю, если дочерний процесс нормально завершился.

WEXITSTATUS(status)

возвращает восемь младших битов возвращаемого значения завершившегося дочернего процесса. Эти биты могли быть установлены в аргументе функции exit() или в аргументе оператора return в функции main(). Этот макрос можно использовать, только если WIFEXITED вернул ненулевое значение.

WIFSIGNALED(status)

возвращает истинное значение, если дочерний процесс завершился из-за неперехваченного сигнала.

WTERMSIG(status)

возвращает номер сигнала, который привел к завершению дочернего процесса. Этот макрос можно использовать только если WIFSIGNALED вернул ненулевое значение.

WIFSTOPPED(status)

возвращает истинное значение, если дочерний процесс, из-за которого функция вернула управление, в настоящий момент остановлен; это возможно только если использовался флаг WUNTRACED.

WSTOPSIG(status)

возвращает номер сигнала, из-за которого дочерний процесс был остановлен. Этот макрос можно использовать только если WIFSTOPPED вернул ненулевое значение.

 

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Идентификатор дочернего процесса, который завершил выполнение, -1 в случае ошибки или нуль, если использовался WNOHANG, но ни один дочерний процесс еще не завершил выполнение (в этом случае errno устанавливается должным образом).  

ОШИБКИ

ECHILD

процесс, указанный в pid, не существует или не является дочерним процессом текущего процесса. (Это может случиться и для собственного дочернего процесса, если обработчик сигнала SIGCHLD установлен в SIG_IGN. Смотри также главу ЗАМЕЧАНИЯ по поводу нитей.)

EINVAL

Аргумент options неверен.

ERESTARTSYS

Использовался флаг WNOHANG, и был пойман неблокированный сигнал или SIGCHLD. Эта ошибка возвращается системным вызовом. Библиотечные функции не могу вернуть ERESTARTSYS, но должны вернуть EINTR.

 

ЗАМЕЧАНИЯ

Стандарт Single Unix Specification описывает флаг SA_NOCLDWAIT (не реализован под Linux), такой, что если он установлен, или обработчик сигнала SIGCHLD установлен в SIG_IGN (что, кстати, не разрешено стандартном POSIX), то завершившиеся дочерние процессы не становятся зомби, а вызов wait() или waitpid() блокируется, пока все дочерние процессы не завершатся, а затем возвращает код ошибки, устанавливая errno в ECHILD.

В ядре Linux нити, управляемые ядром, устройством не отличаются от процесса. Нить -- это просто процесс, который создан уникальным (существующим только в Linux) системным вызовом clone(2); другие процедуры, такие как переносимая версия pthread_create(3), также реализованы с помощью clone(2). Таким образом, если процессы A и B являются братьями, нить A не может подождать с помощью wait() процесс, порожденный потоком B или его потомками, потому что дядя не может ждать с помощью wait() своих племянников. В некоторых Unix-подобных системах, где множественные нити реализованы как принадлежащие одиночному процессу, нить A может ждать с помощью wait() процессы, порожденные своей сестринской нитью B; вам придется переписать код, который делает такие допущения, чтобы он заработал под Linux.  

СООТВЕТСТВИЕ СТАНДАРТАМ

SVr4, POSIX.1  

НАЗВАНИЕ

signal - работа с сигналами ANSI C  

СИНТАКСИС

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

 ОПИСАНИЕ

Системный вызов signal() устанавливает новый обработчик сигнала с номером signum в соответствии с параметром sighandler, который может быть функцией пользователя, SIG_IGN или SIG_DFL. При получении процессом сигнала с номером signum происходит следующее: если устанавливаемое значение обработчика равно SIG_IGN, то сигнал игнорируется; если оно равно SIG_DFL, то выполняются стандартные действия, связанные с сигналом (см. signal(7)). Наконец, если обработчик установлен в функцию sighandler, то сначала устанавливает значение обработчика в SIG_DFL или выполняется зависимая от реализации блокировка сигнала, а затем вызывается функция sighandler с параметром signum.

Использование функции-обработчика сигнала называется "перехватом сигнала". Сигналы SIGKILL и SIGSTOP не могут быть "перехвачены" или игнорированы.  

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Функция signal() возвращает предыдущее значение обработчика сигнала или SIG_ERR при ошибке.  

ВОЗМОЖНОСТЬ ПЕРЕНОСА НА ДРУГИЕ ПЛАТФОРМЫ

Стандартная функция signal() в UNIX устанавливает значение обработчика равным SIG_DFL; System V (а также ядро Linux и libc4,5) выполняют то же самое. С другой стороны, BSD не перезагружает обработчик, а блокирует новые сигналы на время вызова обработчика. Библиотека glibc2 следует поведению BSD. В системе libc5 включение <bsd/signal.h> вместо <signal.h>, приводит к переопределению signal в __bsd_signal, и эта функция начинает работать, как в BSD. Но это нежелательно.

В системе glibc2 при определении тестового макроса типа _XOPEN_SOURCE или при использовании отдельной функции sysv_signal поведение функции будет стандартным. Это тоже нежалательно. Попытаться изменить семантику этой функции при помощи определений и включений - не очень хорошая идея. Лучше избегать использования функции signal вообще, и использовать вместо нее sigaction(2).  

ЗАМЕЧАНИЯ

Согласно POSIX, поведение процесса после игнорирования сигналов SIGFPE, SIGILL или SIGSEGV, не созданных при помощи функций kill(2) или raise(3), не определено. Деление на ноль имеет непредсказуемый характер. На некоторых машинах это приведет к получению сигнала SIGFPE. Более того, деление самого большого по модулю отрицательного числа на -1 приведет к появлению SIGFPE. Игнорирование этого сигнала может привести к появлению бесконечнного цикла.

POSIX (3.3.1.3) не определяет, что случается при SIGCHLD, установленном в SIG_IGN. Поведение BSD и SYSV в этом случае различно. Это приводит к тому, что BSD-программы, устанавливающие поведение SIGCHLD равным SIG_IGN, в Linux не работают.

Использование sighandler_t является расширением GNU. Разные версии libc определяют этот тип; libc4 и libc5 определяют SignalHandler, glibc определяет sig_t и _GNU_SOURCE, а также sighandler_t.  

СООТВЕТСТВИЕ СТАНДАРТАМ

ANSI C  

ИМЯ

signal - список доступных сигналов  

ОПИСАНИЕ

Linux поддерживает нижеописанные сигналы. Некоторые номера сигналов зависят от используемой архитектуры. Сначала идут сигналы, описанные в стандарте POSIX.1.

Сигнал

Значение

Действие

Описание

либо завершение управляющего процесса

SIGINT

 2

A

Прерывание с клавиатуры

SIGQUIT

 3

C

Выход с клавиатуры

SIGILL

 4

C

Несуществующая инструкция

SIGABRT

 6

C

Сигнал прерывания, посланный функцией abort(3)

SIGFPE

 8

C

Ошибка операций с плавающей запятой

SIGKILL

 9

AEF

Kill-сигнал

SIGSEGV

11

C

Обращение к запретной области памяти

SIGPIPE

13

A

Оборванный канал: запись в канал, из которого не читают

SIGALRM

14

A

Сигнал таймера от функции alarm(2)

SIGTERM

15

A

Сигнал завершения

SIGUSR1

30,10,16

A

Первый сигнал, определяемый пользователем

SIGUSR2

31,12,17

A

Второй сигнал, определяемый пользователем

SIGCHLD

20,17,18

B

Потомок остановлен или прекратил выполнение

SIGCONT

19,18,25

Продолжить выполнение, если остановлен

SIGSTOP

17,19,23

DEF

Приостановить выполнение процесса

SIGTSTP

18,20,24

D

Останов введен с терминала

SIGTTIN

21,21,26

D

ввод с терминала у фонового процесса

SIGTTOU

22,22,27

D

вывод на терминал у фонового процесса

Следующие сигналы не входят в стандарт POSIX.1, но описаны в SUSv2.

Сигнал

Значение

Действие

Описание

SIGEMT

7,-,7

SIGSTKFLT

-,16,-

A

Переполнение стека сопроцессора

SIGIO

23,29,22

A

I/O теперь возможно (4.2 BSD)

SIGCLD

-,-,18

Синоним для SIGCHLD

SIGPWR

29,30,19

A

Авария питающего напряжения (System V)

SIGINFO

29,-,-

Синоним для SIGPWR

SIGLOST

-,-,-

A

Потеря файла блокировки

SIGWINCH

28,28,20

B

Изменение размеров окна (4.3 BSD, Sun)

SIGUNUSED

-,31,-

A

Неиспользуемый сигнал (в будущем будет SIGSYS)

(Здесь - является признаком того, что сигнал отсутствует; там, где приведено три значения, первое -- для архитектур alpha и sparc, второе для архитектур i386, ppc и sh, последнее для mips. 29-й сигнал -- это SIGINFO / SIGPWR для alpha, но SIGLOST для sparc.)

Буквы в колонке "Действие" имеют следующее значение:

A

Действие по умолчанию -- прекращение выполнения процесса.

B

Действие по умолчанию -- игнорировать сигнал.

C

Действие по умолчанию -- прекращение выполнения процесса и запись дампа памяти.

D

Действие по умолчанию -- приостановка выполнения процесса.

E

Сигнал не может быть перехвачен.

F

Сигнал не может быть проигнорирован.

 

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1  

ОШИБКИ

SIGIO и SIGLOST имеют одинаковое значение. Последний закомментирован в исходниках ядра, но некоторые программы продолжают думать, что 29-й сигнал -- это SIGLOST.  

НАЗВАНИЕ

getrlimit, getrusage, setrlimit - считывает/устанавливает ограничения использования ресурсов  

СИНТАКСИС

#include <sys/time.h> #include <sys/resource.h> #include <unistd.h>

int getrlimit(int resource, struct rlimit *rlim); int getrusage(int who, struct rusage *usage); int setrlimit(int resource, const struct rlimit *rlim);  

ОПИСАНИЕ

getrlimit и setrlimit соответственно получают и устанавливают ограничения использования ресурсов. Значение resource должно быть одним из:

RLIMIT_CPU     /* системное время в секундах */ RLIMIT_FSIZE   /* максимальный размер файла */ RLIMIT_DATA    /* максимальный размер данных */ RLIMIT_STACK   /* максимальный размер стека */ RLIMIT_CORE    /* максимальный размер файла core */ RLIMIT_RSS     /* максимальный rss */ RLIMIT_NPROC   /* максимальное количество процессов */ RLIMIT_NOFILE  /* максимальное количество открытых файлов */ RLIMIT_MEMLOCK /* максимальный объем заблокированного адресного пространства*/ RLIMIT_AS              /* максимальный объем адресного пространства */

Можно снять все ограничения с ресурса путем установки ограничения на RLIM_INFINITY. RLIMIT_OFILE в BSD называется RLIMIT_NOFILE.

Структура rlimit описывается следующим образом :

struct rlimit {

rlim_t rlim_cur;

rlim_t rlim_max;

};

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

struct rusage {

struct timeval ru_utime; /* время работы пользователя */

struct timeval ru_stime; /* использованное системное время */

long ru_maxrss; /* максимальный rss */

long ru_ixrss; /* общий объем разделяемой памяти */

long ru_idrss; /* общий объем неразделяемых данных */

long ru_isrss; /* общий объем неразделяемых стеков */

long ru_minflt; /* количество процессов подгрузки страницы */

long ru_majflt; /* количество ошибок при обращении к странице */

long ru_nswap; /* количество обращений к диску при подкачке */

long ru_inblock; /* количество операций блокового ввода */

long ru_oublock; /* количество операций блокового вывода */

long ru_msgsnd; /* количество отправленных сообщений */

long ru_msgrcv; /* количество принятых сообщений */

long ru_nsignals; /* количество принятых сигналов */

long ru_nvcsw; /* количество переключений контекста процессом */

long ru_nivcsw; /* количество принудительных переключений контекста */

};

 

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

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

КОДЫ ОШИБОК

EFAULT

rlim или usage указывают на недоступную область адресного пространства.

EINVAL

getrlimit или setrlimit вызывается неправильным resource, или getrusage вызывается неправильным who.

EPERM

производится попытка использования setrlimit() для установки мягких (advisory) или жестких (mandatory) ограничений поверх текущих жестких при отсутствии прав суперпользователя, или суперпользователь пытается установить значение RLIMIT_NOFILE больше текущего максимума ядра.

 

СООТВЕТСТВИЕ СТАНДАРТАМ

SVr4, BSD 4.3  

ЗАМЕЧАНИЕ

Подключение <sys/time.h> сейчас уже не требуется, но улучшает портируемость. (В самом деле, struct timeval определяется в <sys/time.h>.)

Вышеописанная структура была взята из BSD 4.3 Reno. Не все поля имеют смысл в Linux. Сейчас (в Linux 2.4) поддерживаются только поля ru_utime, ru_stime, ru_minflt, ru_majflt, и ru_nswap

Соседние файлы в папке Lecture 2_01