Программирование для Linux. Профессиональный подход - страница 25

стр.

Форматы вывода команды >ps

В опции >-o через запятую указываются столбцы которые должны быть включены в вывод команды >ps. Например, команда >ps -о pid,user,start_time,command отображает идентификатор процесса, имя его владельца, время запуска а также команду, соответствующую процессу. Полный список опций и столбцов можно узнать на >man-странице команды >ps. Имеются три предопределенных формата вывода: >-f (полный листинг), >-l (длинный листинг) и >-j (вывод заданий)

Ниже приведено несколько первых и последних строк, выдаваемых этой командой в нашей системе:

>% ps -e -о pid,ppid,command

>PID PPID COMMAND

>  1    0 init [5]

>  2    1 [kflushd]

>  3    1 [kupdate]

>...

>21725 21693 xterm

>21727 21725 bash

>21728 21727 ps -e -o pid,ppid,command

Заметьте: родительский идентификатор команды >ps, 21727, соответствует интерпретатору >bash, из которого была вызвана команда. В свою очередь, родительский идентификатор интерпретатора, 21725, принадлежит программе >xterm — эмулятору терминала, в котором выполняется интерпретатор.

3.1.3. Уничтожение процесса

Для уничтожения процесса предназначена команда >kill. Ей достаточно указать идентификатор требуемого процесса.

Команда >kill посылает процессу сигнал >SIGTERM, являющийся запросом на завершение.[10] По умолчанию, если в программе отсутствует обработчик данного сигнала, процесс просто завершает свою работу. О сигналах речь пойдет в разделе 3.3, "Сигналы".

3.2. Создание процессов

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

3.2.1. Функция system()

Функция >system() определена в стандартной библиотеке языка С и позволяет вызывать из программы системную команду, как если бы она была набрана в командной строке. По сути, эта функция запускает стандартный интерпретатор Bourne shell (>/bin/sh) и передает ему команду на выполнение. Например, программа, представленная в листинге 3.2, вызывает команду >ls -l /, отображающую содержимое корневого каталога.

Листинг 3.2. (system.c) Использование функции >system()

>#include


>int main() {

> int return_value;

> return_value = system("ls -l /");

> return return_value;

>}

Функция >system() возвращает код завершения указанной команды. Если интерпретатор не может быть запущен, возвращается значение 127, а в случае возникновения других ошибок — -1.

Поскольку функция >system() запускает интерпретатор команд, она подвержена всем тем ограничениям безопасности, что и системный интерпретатор. Рассчитывать на наличие какой-то конкретной версии Bourne shell не приходится. В большинстве UNIX-систем программа >/bin/sh представляет собой символическую ссылку на другой интерпретатор. В Linux — это >bash (Bourne-Again SHell), причем в разных дистрибутивах присутствуют разные его версии. Вызов из функции >system() программы с привилегиями пользователя >root также может иметь неодинаковые последствия в разных системах. Таким образом, лучше создавать процессы с помощью функций >fork() и >exec().

3.2.2. Функции fork() и exec()

В DOS и Windows API имеется семейство функций >spawn(). Они принимают в качестве аргумента имя программы, создают новый экземпляр ее процесса и запускают его. В Linux нет функции, которая делала бы все это за один заход. Вместо этого имеется функция >fork(), создающая дочерний процесс, который является точной копией родительского процесса, и семейство функций >exec(), заставляющих требуемый процесс перестать быть экземпляром одной программы и превратиться в экземпляр другой программы. Чтобы создать новый процесс, нужно сначала с помощью функции >fork() создать копню текущего процесса, а затем с помощью функции >exec() преобразовать одну из копий в экземпляр запускаемой программы.

Вызов функции fork()

Вызывая функцию >fork(), программа создает свой дубликат, называемый дочерним процессом. Родительский процесс продолжает выполнять программу с той точки, где была вызвана функция >fork(). То же самое делает и дочерний процесс.

Как же различить между собой оба процесса? Во-первых, дочерний процесс — это новый, только что появившийся в системе процесс, поэтому его идентификатор отличается от идентификатора родительского процесса. Таким образом, программа может вызвать функцию