Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab-2Создание процесса.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
95.23 Кб
Скачать

Состояние завершения процесса

Если значение состояния выхода дочернего процесса - нуль, то значение состояния, сообщенное waitpid или wait - также нуль. Можно проанализировать другую информацию, закодированную в возвращенном значении состояния, используя следующие макрокоманды. Эти макрокоманды определены в заглавном файле "sys/wait.h".

int WIFEXITED (int status)

Эта макрокоманда возвращает значение отличное от нуля если дочерний процесс завершен exit или _exit.

int WEXITSTATUS (int status)

Если WIFEXITED - истина, эта макрокоманда возвращает 8 битов младшего разряда значения состояния выхода из дочернего процесса.

int WIFSIGNALED (int status)

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

int WTERMSIG (int status)

Если WIFSIGNALED - истина, эта макрокоманда возвращает номер сигнала, который завершил дочерний процесс.

int WCOREDUMP (int status)

Эта макрокоманда возвращает значение отличное от нуля, если дочерний процесс завершен и произведен core-файл.

int WIFSTOPPED (int status)

Эта макрокоманда возвращает значение отличное от нуля, если дочерний процесс остановлен.

int WSTOPSIG (int status)

Если WIFSTOPPED - истина, эта макрокоманда возвращает номер сигнала, который заставил дочерний процесс остановиться.

Пример Создания Процесса

Приведем пример программы, показывающий, как можно написать функцию, выполняющую внешнюю программу. Она выполняет аргумент command, используя " sh -c command ".

#include <stddef.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

#define SHELL "/bin/sh"

int

my_system (const char *command)

{

int status;

pid_t pid;

pid = fork ();

if (pid == 0)

{

execl (SHELL, SHELL, "-c", command,

NULL);

_exit (EXIT_FAILURE);

}

else if (pid < 0)

status = -1;

else

if (waitpid (pid, &status, 0) != pid)

status = -1;

return status;

}

В примере необходимо обратить внимание на следующее.

Первый аргумент argv, представляет имя выполняемой программы. Именно поэтому, в обращении к execl, SHELL встречается в вызове один раз, чтобы определить выполняемую программу, и второй раз, чтобы обеспечить значение для argv [0].

Вызов execl в дочернем процессе не возвращает управление, если он успешен. Если он терпит неудачу, необходимо выполнить определенные действия, чтобы заставить дочерний процесс завершиться. Правильное поведение для дочернего процесса - сообщить об ошибке родительскому процессу.

Вызовите _exit, чтобы выполнить это. Причина для использования _exit вместо exit состоит в том, чтобы избежать закрытия полностью буферизированных потоков типа stdout. Буфера этих потоков возможно содержат данные, которые были скопированы из родительского процесса функцией fork, эти данные будут выводиться в конечном счете родительским процессом. Вызов exit в дочернем вывел бы данные дважды.

Описания полезных функций

НАЗВАНИЕ

sleep - переход в режим ожидания на указанное количество секунд  

СИНТАКСИС

#include <unistd.h>

unsigned int sleep(unsigned int seconds);

ОПИСАНИЕ

sleep() переводит текущий процесс в режим ожидания либо на seconds секунд, либо на время до получения сигнала, который не может быть проигнорирован.

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

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

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

POSIX.1

НАЙДЕННЫЕ ОШИБКИ

sleep() может применяться совместно с SIGALRM; использование вызовов alarm() и sleep() одновременно является крайне нежелательным.

Использование longjmp(), вызываемой из функции обработки сигнала, или изменение метода обработки сигнала SIGALRM во время режима ожидания может привести к непредсказуемым последствиям.

НАЗВАНИЕ

perror - выводит сообщение о системной ошибке  

СИНТАКСИС

#include <stdio.h>

void perror(const char *s);

#include <errno.h>

const char *sys_errlist[]; int sys_nerr;

ОПИСАНИЕ

Процедура perror() выводит в стандартный поток ошибки сообщения, описывая ошибку, произошедшую при последнем системном вызове или вызове библиотечной функции. Сначала (если s не равно NULL и *s не равно NULL) выводится строка s, затем двоеточие, пробел и сообщение, завершающееся переводом строки. Для большего удобства параметы строки должны содержать имя функции, вызвавшей ошибку. Номер ошибки извлекается из внешней переменной errno, которая устанавливается в случае ошибки, но не "очищается" в случае нормального завершения работы. Глобальный список ошибок sys_errlist[], упорядоченный в соответствии с errno, может быть использован для вывода сообщений об ошибке без перевода строки. Наибольший номер в таблице имеет sys_nerr -1. Будьте осторожны при непосредственном использовании этого массива. Новые элементы не могут быть вписаны в sys_errlist[]. Если системный вызов завершается ошибкой, то возвращается -1 и переменная errno устанавливается равной коду ошибки (эти величины могут быть найдены в <errno.h>). Многие системные функции работают именно так. Функция perror() позволяет отображать коды ошибок в понятном человеку виде. Заметьте, что errno не является определенной после нормального завершения системного вызова: этот вызов может изменить переменную кода ошибки, даже если завершился удачно (например, потому, что он использовал другие функции, завершившиеся ошибкой). Таким образом, если за вызовом, завершившимся ошибкой, непосредственно не следует perror, то величина errno должна быть сохранена.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]