Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метод_ПСРВ.doc
Скачиваний:
26
Добавлен:
12.02.2016
Размер:
1.6 Mб
Скачать

2. Упражнения

УПРАЖНЕНИЕ 2.1.

Написать программу, которая, используя приведенные выше функции, открывает заранее подготовленные файлы и демонстрирует возможности записи и чтения информации из них. При этом необходимо реализовать запись информации (из одного файла в другой) в конец, в начало, в середину файла.

УПРАЖНЕНИЕ 2.2.

Продемонстрировать возможности использования дублирования дескрипторов файлов. Необходимо выполнять контроль правильности выполняемых операций.

УПРАЖНЕНИЕ 2.3.

Проанализируйте результаты и отметьте выявленные ограничения.

3. Содержание отчёта

  1. Номер, название и цель работы.

  2. Текст программы.

  3. Результаты работы программы и результаты проведенного анализа.

Практическое занятие №15 Организация процессов вQnx

Цель – ознакомиться со способами организации дочерних процессов, предоставляемыми системой QNX

Системой предоставляется пять основных способов организации процессов:

  • разветвление текущего процесса на процесс-родитель и процесс потомок (системный вызов fork);

  • подмена выполняемой процессом задачи (системный вызов exec);

  • порождение независимого процесса (системный вызов spawn);

  • выполнение системной утилиты QNX (системный вызов system);

  • (системный вызов vfork)

Более подробная информация, включающая в себя синтаксис команд, их описание и примеры применения предоставлена в качестве справочного материала.

1. Методические указания по выполнению практической работы

Данные методические указания являются лишь одним из способов реализации поставленной задачи. Выбор способа реализации полученного задания предоставляется на усмотрение студента. Однако, выполненное задание должно в полной мере соответствовать условиям поставленной задачи.

В предоставляемом примере задача по ведению базы данных разбита на три модуля:

  • модуль input.o производит ввод данных в базу данных (база данных имеет произвольный формат);

  • модуль output.o позволяет производить просмотр содержимого базы данных;

  • модуль process.o производит обработку данных, содержащихся в базе данных;

  • модуль main.o является основной программой, из которой происходит вызов ранее описанных модулей.

Для большей наглядности рекомендуется каждый из составных модулей снабдить средствами вывода идентификатора текущего процесса.

Информационная схема, описывающая направление информационных потоков приведена на рисунке 1.

На рисунке 2 представлена блок-схема алгоритма работы основной программы, поскольку именно в ней содержатся системные вызовы дочерних процессов.

Рис. 1. Направление информационных потоков между модулями

1.1. Файл main.O

Эта основная программа производит создание дочерних процессов различными

// способами, такими как: fork, exec, spawn

# include <fcntl.h>

# include <sys/stat.h>

# include <errno.h>

# include <semaphore.h>

# include <stdio.h>

# include <stdlib.h>

# include <spawn.h>

int error; // хранение ошибки

int child_pid; // идентификатор дочернего

// процесса

int main ()

{printf ("Идентификатор родительского процесса равен %d\n", getpid ());

fflush (stdout);

// Дочерний процесс в данном примере не выполняет никаких действий

if (child_pid = fork ())

{printf ("\n Идентификатор родительского процесса равен: %d\n",getpid());

// выполнение системной утилиты ls (чтение оглавления каталога)

// посредством функции system

system (“ls”);

// родительский процесс дожидается завершения выполнения запускаемой

// программы

printf ("\n Выполнение внешней программы посредством функции spawnl

\n");

// Обработка возможных ошибок

if (spawnl(P_WAIT, "input.o", "input.o",NULL, NULL)==-1)

printf ("Возникла ошибка!!! - %s", strerror(error));

// родительский процесс не дожидается завершения выполнения запускаемой

// программы

printf ("\n Выполнение внешней программы посредством функции spawnl

\n");

// Обработка возможных ошибок

if (spawnl(P_WAIT, "output.o", "output.o",NULL, NULL))

printf ("Возникла ошибка!!! - %s", strerror(error));

printf ("\n Выполнение внешней программы посредством функции execl \n");

if (execl("process.o", "process.o",NULL)==-1)

printf ("Возникла ошибка!!! - %s", strerror(error));

printf ("\n Эта строка не будет появляться на экране!!!");}

else {printf ("Идентификатор дочернего процесса равен: %d\n",getpid ());}

}

Рис. 2. Алгоритм выполнения основной программы

Приведем некоторое словесное описание работы программы.

Основная программа содержит в себе системный вызов fork(), который производит порождение дочернего процесса. Для обоих процессов (как родительского, так и дочернего) производится вывод на экран идентификаторов процессов. Поскольку тело дочернего процесса более ничего не содержит, он завершается, в то время как родительский процесс продолжает своё выполнение.

Родительским процессом производится выполнение системного вызова system(), результаты выполнения которого можно увидеть на экране в виде листинга содержимого текущего каталога. После этого осуществляется последовательный запуск трёх внешних модулей при помощи различных системных средств.

Самая последняя строка в родительском процессе приведена лишь для наглядности действий, выполняемых системным вызовом execl().

Следует отметить, что в данной лабораторной работе системный вызов vfork() не используется. По своим возможностям он очень сходен с системным вызовом fork() , с тем лишь отличием, что в отличие от вызова fork() вызовом vfork() происходит порождение двух полностью независимых процессов.