Работа с процессами в ОС Linux. Знакомство с функциями ОС Linux для работы с процессами. Получение первоначальных навыков управления состояниями процессов

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

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

Лабораторная работа №2

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

Цели: Изучение создания, контроля и завершения процессов в ОС Linux. 

Задачи: Знакомство с функциями ОС Linux для работы с процессами. Получение первоначальных навыков управления состояниями процессов. 

Срок выполнения: 2 недели

Общие сведения

Процесс в Unix/Linux представляет собой единицу работы вычислительной системы, которой операционная система выделяет ресурсы. Каждый процесс в системе имеет свой уникальный идентификатор процесса (PID), представляемый целым числом. Существует так же идентификатор родительского процесса (PPID). 

Процесс может порождать другой процесс. Порождение нового процесса в ОС 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. Запустите любую свою программу, используя в конце & (например:

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

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