Статья: Теория вычислительных процессов и структур
5. Разработать программу «интерпретатор команд», которая воспринимает команды, вводимые с клавиатуры, и осуществляет их корректное выполнение. Предусмотреть контроль ошибок.
Лабораторная работа №3
Взаимодействие процессов
Цель работы – создание и изучение взаимодействия процессов, созданных при помощи вызова fork.
Взаимодействие процессов
Теоретическая часть
Созданный при помощи вызова fork дочерний процесс является почти точной копией родительского. Все переменные в дочернем процессе будут иметь те же самые значения, что и в родительском (единственным исключением является значение, возвращаемое самим вызовом fork). Так как данные в дочернем процессе являются копией данных в родительском процессе и занимают другое абсолютное положение в памяти, важно знать, что последующие изменения в одном процессе не будут затрагивать переменные в другом.
Аналогично все файлы, открытые в родительском процессе, также будут открытыми и в потомке, при этом дочерний процесс будет иметь свою копию связанных с каждым файлом дескрипторов. Тем не менее файлы, открытые до вызова fork, остаются тесно связанными в родительском и дочернем процессах. Это обусловлено тем, что указатель чтения-записи для каждого из таких файлов используется совместно родительским и дочерним процессами благодаря тому, что он поддерживается системой и существует не только в самом процессе. Следовательно, если дочерний процесс изменяет положение указателя в файле, то в родительском процессе он также окажется в новом положении. Это поведение демонстрирует следующая программа, в которой использованы процедура fatal, описанная в предыдущей лабораторной работе, а также новая процедура printpos. Дополнительно введено допущение, что существует файл с именем data длиной не меньше 20 символов:
#include <unistd.h>
#include <fcntl.h>
main()
{
int fd;
pid_t pid; /*Идентификатор процесса*/
char buf [10]; /*Буфер данных для файла*/
if (( fd = open ( “data”, O_RDONLY)) == -1)
fatal (“Ошибка вызова open”);
read (fd, buf, 10); /* Переместить вперед указатель файла */
printpos (“До вызова fork”, fd);
/* Создать два процесса */
switch (pid = fork ()) {
case -1: /* Ошибка */
fatal (“Ошибка вызова fork ”);
break;
case 0: /* Потомок */
printpos (“Дочерний процесс до чтения”, fd);
read (fd, buf, 10);
printpos (“Дочерний процесс после чтения”, fd);
break;