Работа с процессами в ОС Linux

Страницы работы

Фрагмент текста работы

Новый процесс порождается системным вызовом fork(), который создает дочерний процесс - копию родительского. Прототип данной функции находится в <unistd.h>. В дочернем процессе выполняется та же программа, что и в родительском, и когда дочерний процесс начинает выполняться, он выполняется с точки возврата из системного вызова fork(). Системный вызов fork() возвращает родительскому процессу PID дочернего процесса, а дочернему процессу - 0. По коду возврата вызова fork() дочерний процесс может "осознать" себя как дочерний. Свой PID процесс может получить при помощи системного вызова getpid(), а PID родительского процесса - при помощи системного вызова getppid(). Если требуется, чтобы в дочернем процессе выполнялась программа, отличная от программы родительского процесса, процесс может сменить выполняемую в нем программу при помощи одного из системных вызовов семейства exec. Все вызовы этого семейства загружают для выполнения в процессе программу из заданного в вызове файла и отличаются друг от друга способом передачи параметров этой программе. Таким образом, наиболее распространенный контекст применения системного вызова fork() выглядит примерно так:

/* порождение дочернего процесса и запоминание его PID */

if (!(ch_pid=fork()))

/* загрузка другой программы в дочернем процессе */

exec(программа);

else /* продолжение родительского процесса */

Пример программы на языке С.

#include <stdio.h>

#include <unistd.h>/* contains fork prototype */

int main(void)

{

int pid;

printf("Hello World!\n");

printf("I am the parent process and my PID is : %d.\n",getpid());

printf("Here I am before use of forking\n");

pid = fork();

printf("Here I am just after forking\n");

if (pid == 0)

printf("I am the child process and PID is :%d.\n",getpid());

else

printf("I am the parent process and PID is: %d.\n",getpid());

return 0;

}

Примерный результат работы программы:

Hello World!

I am the parent process and my PID is : 23951.

Here I am before use of forking

Here I am just after forking

Here I am just after forking

I am the child process and my PID is :23952.

I am the parent process and my PID is: 23951.

Завершение процесса

Нормальное завершение процесса происходит при достижении конца функции main или при выполнении системного вызова exit(). При этом процесс устанавливает некоторый код своего завершения, который может быть прочитан процессом-предком. Существует общепринятое соглашение, по которому 0 означает нормальное завершение, а любое другое значение – ошибку или необычное происшествие. Множество стандартных библиотечных вызовов используют ошибки, определенные в <sys/stat.h>.

Принудительное завершение процесса извне может быть выполнено при помощи системного вызова kill(), посылающего процессу сигнал. С сигналами мы познакомимся при выполнении следующих лабораторных работ, пока же только отметим, что гарантированно "убить" процесс, имеющий PID = p, можно системным вызовом kill(p,SIGKILL).

Ожидание завершения процесса

Процесс-предок может ожидать завершения процесса-потомка (или процессов-потомков) при помощи системных вызовов wait() или waitpid(). Прототипы этих функций находятся в <sys/wait.h>. Если процесс-потомок еще не завершился, процесс-предок переводится таким системным вызовом в состояние ожидания до завершения процесса-потомка (впрочем, процесс может и не ожидать завершения потомка, а только проверить, завершился ли он). Эти системные вызовы позволяют также процессу предку узнать код завершения потомка.

Пример программы.

#include <stdio.h>

#include <sys/wait.h> /* contains prototype for wait */

int main(void)

{

int pid;

int status;

printf("Hello World!\n");

pid = fork( );

if (pid == -1)

{

perror("bad fork");

exit(1);

}

if (pid == 0)

printf("\t I am the child process.\n");

else

{

wait(&status); /* parent waits for child to finish */

printf("I am the parent process.\n");

}

return 0;

}

Результат работы программы:

Hello World!

I am the child process.

I am the parent process.

Задания на лабораторную работу:

  1. Изучите команды ps и kill. Запустите любую свою программу, используя в конце & (например: ./a.out & ). Дайте письменно объяснение результата работы команды ps. Опишите также, как завершить процесс a.out ?
  2. Изучите команды ОС Linux, предназначенные для управления процессами и мониторинга состояния операционной системы: jobs,fg, bg, top.  Объясните письменно назначение и использование каждой из команд, а также их параметров. Подробно опишите действия, необходимые для переключения процесса в фоновый режим выполнения и возврата из этого режима.
  3. Изучите функции семейства exec, а именно execv(), execl(), execvp()и execlp(). Объясните письменно разницу между этими функциями.
  4. Напишите программу на языке С/С++, удовлетворяющую следующим условиям.

1)  1)  Программа должна создать четыре процесса и ожидать окончания их выполнения.

2)  2)  Порядок создания процессов задается с командной строки (передается в виде параметров в функцию main), например:

./a.out 1 3 2 4

3)  3)  Каждый процесс и основная программа должны выводить на экран сообщения о начале и завершении своей работы в следующем формате:

PID PPID “сообщение” “время сообщения”

4)  4)  Для получения текущего времени используйте функцию ctime() из <time.h>.

5)  5)  Процессы должны использовать функции, перечисленные по порядку:

execv(), execl(), execvp()и execlp() с любыми командами ОС Linux внутри. Вы можете также использовать любые свои программы.

6)  6)  Программа должна анализировать и сообщать о причинах завершения процессов, используя переменную errno. Все значения ошибок определены в заголовочном файле <sys/errno.h> .

Содержание отчета по лабораторной работе:

  1. Цель и описание лабораторной работы.
  2. Ответы на вопросы №1, 2, 3.
  3. Текст программы (задание №4) и результаты работы программы

Похожие материалы

Информация о работе

Тип:
Задания на лабораторные работы
Размер файла:
42 Kb
Скачали:
0