
- •Тема 1. Основы Unix
- •Структура unix
- •Сравнение Windows 2000 и Unix
- •Сравнение FreeBsd и Linux
- •Командные интерпретаторы Unix
- •Тема 2. Команды интерпретатора
- •2.1 Команды работы с файловой системой
- •2.2 Создание ссылок
- •2.3 Конвейеры и перенаправление ввода-вывода
- •Тема 3. Сценарии
- •3.1 Редактирование исходных файлов
- •3.2 Работа с командным интерпретатором
- •3.3 Переменные
- •3.4 Взаимодействие с пользователем
- •3.5 Арифметические операции в сценариях
- •Тема 4. Операторы сценариев
- •4.1 Операторы цикла
- •4.2 Другие операторы
- •4.3 Арифметические операторы and и or
- •Код завершения
- •Файловые дескрипторы
- •Отладка сценариев
- •4.7 Запись команд
- •Использование специальных символов
- •Тема 5. Файловая система FreeBsd
- •Разделы жесткого диска
- •5.2 Файловые системы
- •Монтирование файловых систем
- •Блоки и индексные дескрипторы
- •5.5 Пользователи и группы
- •5.6 Права доступа к файлам и каталогам
- •5.7 Добавление и удаление учетных записей пользователей
- •5.8 Управление процессами
- •Тема 6. Работа с файлами в Unix
- •6.2 Файловые функции Unix
- •6.3 Пример программы для обработки файла
- •Тема 7. Межмашинное взаимодействие
- •7.1 Сокеты
- •7.2 Функции для программирования сокетов
- •Тема 8. Программирование процессов
- •8.1 Информация о процессах
- •8.2 Создание порожденного процесса
- •8.3 Программные каналы
- •Тема 9. Web и Ftp сервисы
- •9.1 Конфигурирование Web-сервера
- •9.2 Конфигурирование ftp-сервера
- •Подключение к Internet
Тема 8. Программирование процессов
8.1 Информация о процессах
Получить информацию о запущенных процессах можно с помощью команды top. Команда выполняется в реальном времени – выводимая информация постоянно обновляется. Колонка PID содержит идентификатор процесса, т.е. число, присваиваемое каждому процессу при запуске.
Команда отображает мгновенное состояние процесса на момент запуска команды.
Завершить процесс можно командой kill, при этом в качестве аргумента команды задается PID процесса.
Можно также командой изменить приоритет процесса.
8.2 Создание порожденного процесса
Для создания порожденного процесса используется функция fork:
pid_t fork (void).
Тип pid_t определен в <sys/types.h> и соответствует типу int. При успешном выполнении создается порожденный процесс и функция возвращает идентификатор этого порожденного процесса родительскому процессу. Порожденный процесс получает от fork нулевой код возврата.
Как порожденный процесс, так и родительский планируются ядром Unix для выполнения независимо, а очередность запуска этих процессов зависит от реализации ОС. По завершении вызова fork выполнение обоих процессов возобновляется. Возвращаемое значение вызова fork мспользуется для того, чтобы определить, является ли процесс порожденным или родительским.
Таким образом, родительский и порожденный процессы могут выполнять различные задачи одновременно.
Функция exit завершает процесс. Ее прототип имеет вид:
void exit (int exit_code),
где exit_code – код завершения процесса.
Простейший пример создания нового процесса:
#include <iostream.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{ int status;
if (!fork())
{ cout << "Child process\n";
exit(0);
};
cout << "Parent process\n";
}
Родительский процесс использует функции wait и waitpid для перехода в режим ожидания завершения порожденного процесса и для выборки его статуса завершения. Прототипы этих функций выглядят так:
pid_t wait (int status_p);
pid_t waitpid (pid_t child_pid, int* status_p, int options).
Функция wait приостанавливает выполнение родительского процесса до тех пор, пока один из его порожденных процессов не завершится. Если порожденный процесс уже завершился, функция wait возвратится со статусом завершения порожденного процесса status_p, а возвращаемым значением будет PID порожденного процесса.
Функция waitpid является более универсальной, в ней с помощью аргумента child_pid можно указать, завершения какого из порожденных процессов следует ожидать.
Для того, чтобы вызывающий процесс изменил свой контекст (регистры, адресное пространство и др.) и выполнил другую программу, используется функция exec. Есть несколько версий этой функции, одна из них execl:
int execl (const char* path, const char* arg, …).
Первый аргумент функции является либо полным путевым именем, либо именем файла программы, подлежащей исполнению. Аргументы arg являются аргументами для программы, вызванной функцией exec. Они отображаются в переменную argv функции main новой программы. При этом arg отображается в argv[0], значение, указанное после arg, - в argv[1] и т. д. Список аргументов заканчивается нулевым значением.
Пример.
#include <stdio.h>
#include <unistd.h>
int main()
{
char s1[8]="string1", s2[4]="string2";
execl ("./b.out", s1, s2, 0);
return 0;
}
Здесь вызывается программа b.out, скомпилированная из файла
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("%s\n",argv[0]);
printf("%s\n",argv[1]);
return 0;
}
В результате выполнения примера будут выведены строки string1
string2
Большинство программ вызывают exec в порожденном процессе, так как выполнение родительского процесса после вызова exec желательно продолжить. Однако программа может вызвать exec без fork, аfork без exec.