Изучение ос linux и работа с процессами. Системная функция Fork. Цель лабораторной работы



бет2/2
Дата26.01.2023
өлшемі48 Kb.
#166512
1   2
Байланысты:
Лабораторная работа №3

Алгоритм fork
входная информация: отсутствует
выходная информация: для родительского процесса-идентифи- катор (PID) порожденного процесса;
для порожденного процесса - 0
{
проверить доступность ресурсов ядра;
получить свободное место в таблице процессов и уникальный код идентификации (PID);
проверить, не запустил ли пользователь слишком много процессов;
сделать пометку о том, что порождаемый процесс находится в состоянии "создания";
скопировать информацию в таблице процессов из записи, соответствующей родительскому процессу, в запись, соответствующую порожденному процессу;
увеличить значения счетчиков ссылок на текущий каталог и на корневой каталог (если он был изменен);
увеличить значение счетчика открытий файла в таблице файлов;
сделать копию контекста родительского процесса (адресное пространство, команды, данные, стек) в памяти;
поместить в стек фиктивный уровень системного контекста над уровнем системного контекста, соответствующим порожденному процессу;
фиктивный контекстный уровень содержит информацию, необходимую порожденному процессу для того, чтобы знать все о себе и будучи выбранным для исполнения запускаться с этого места;
если (в данный момент выполняется родительский процесс)
{
перевести порожденный процесс в состояние "готовности к выполнению";
возвратить (идентификатор порожденного процесса);
/* из системы пользователю */
}
в противном случае
/* выполняется порожденный процесс */
{
записать начальные значения в поля синхронизации адресного пространства процесса;
возвратить (0); /* пользователю */
}
}
В процессе выполнения системного вызова fork() порождается копия родительского процесса и возвращение из системного вызова будет происходить уже как в родительском, так и в порожденном процессах. Этот системный вызов является единственным, который вызывается один раз, а при успешной работе возвращается два раза (один раз в процессе-родителе и один раз в процессе-ребенке)! После выхода из системного вызова оба процесса продолжают выполнение регулярного пользовательского кода, следующего за системным вызовом.
Для того, чтобы после возвращения из системного вызова fork() процессы могли определить, кто из них является ребенком, а кто родителем, и, соответственно, по-разному организовать свое поведение, он возвращает в них разные значения. При успешном создании нового процесса в процесс-родитель возвращается положительное значение равное идентификатору процесса-ребенка. В процесс-потомок же возвращается значение 0. Если по какой-либо причине создать новый процесс не удалось, то системный вызов вернет в инициировавший его процесс значение -1. Таким образом, общая схема организации различной работы процесса-потомка и процесса-родителя выглядит так:
pid = fork();
if(pid == -1)
{
...
/* ошибка */
...
}
else if (pid == 0)
{
...
/* ребенок */
...
} else
{
...
/* родитель */
...
}
Системная функция fork требует, чтобы ядро скопировало содержимое областей процесса. Если же область разделяемая (разделяемый текст команд или разделяемая память), ядру нет надобности копировать область физически; вместо этого оно увеличивает значение счетчика ссылок на область, позволяя родительскому и порожденному процессам использовать область совместно. Если область не является разделяемой и ядру нужно физически копировать ее содержимое, оно выделяет новую запись в таблице областей, новую таблицу страниц и отводит под создаваемую область физическую память. В качестве примера рассмотрим программу в которой родительский и порожденный процессы разделяют доступ к файлу. Процесс порождает с помощью функции fork поток и копирует области родительского процесса. Область команд процесса является разделяемой, поэтому поток может использовать эту область совместно с процессом . Однако области данных и стека родительского процесса являются его личной принадлежностью (имеют частный тип), поэтому потоку нужно скопировать их содержимое во вновь выделенные области.
Программа, в которой родительский и порожденный процессы разделяют доступ к файлу
#include
int fdrd, fdwt;
char c;
main(argc, argv)
int argc;
char *argv[];
{
if (argc != 3)
exit(1);
if ((fdrd = open(argv[1],O_RDONLY)) == -1)
exit(1);
if ((fdwt = creat(argv[2],0666)) == -1)
exit(1);
fork();
/* оба процесса исполняют одну и ту же программу */
rdwrt();
exit(0);
}
rdwrt()
{
for(;;)
{
if (read(fdrd,&c,1) != 1)
return;
write(fdwt,&c,1);
}
}


Порядок выполнения работы:
1. Ознакомиться с теоретическим материалом, предложенным выше.
2. Изучить алгоритм и функцию порождения процессов и потоков. Написать программу на языке Си.
3. Подготовить отчет о полученных результатах с приведенными образцами выполненных заданий.

Достарыңызбен бөлісу:
1   2




©engime.org 2024
әкімшілігінің қараңыз

    Басты бет