Добавил:
Факультет ИКСС, группа ИКВТ-61 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LAB / WORK_7 / лаб_раб_7

.pdf
Скачиваний:
36
Добавлен:
20.02.2019
Размер:
163.92 Кб
Скачать

ФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» (СПбГУТ)

Кафедра программной инженерии и вычислительной техники

Отчёт

по лабораторной работе №7 на тему:

«Разработка приложений под Linux»

по дисциплине «Операционные системы»

Выполнил: студент группы ИКВТ-61, Козырев А.Б.

«

 

»

 

 

2018

г. ___________/А.Б. Козырев/

Принял: __к.т.н.

Дагаев А.В.

«

 

»

 

 

2018

г. ___________/_А.В. Дагаев/

САНКТ-ПЕТЕРБУРГ

2018

Задание: разработать приложение, использующее несколько процессов и объекты синхронизации под Linux.

Объект синхронизации: pipe

Исходный код

#include<stdio.h>

#include<unistd.h>

int main() {

int pipefds[2]; int returnstatus; int pid;

char writemessages[2][20]={"Hi", "Hello"}; char readmessage[20];

returnstatus = pipe(pipefds); if (returnstatus == -1) {

printf("Unable to create pipe\n"); return 1;

}

pid = fork();

if (pid == 0) {

read(pipefds[0], readmessage, sizeof(readmessage)); printf("Child Process - Reading from pipe – Message 1 is %s\n",

readmessage);

read(pipefds[0], readmessage, sizeof(readmessage)); printf("Child Process - Reading from pipe – Message 2 is %s\n",

readmessage); } else {

printf("Parent Process - Writing to pipe - Message 1 is %s\n", writemessages[0]);

write(pipefds[1], writemessages[0], sizeof(writemessages[0])); printf("Parent Process - Writing to pipe - Message 2 is %s\n",

writemessages[1]);

write(pipefds[1], writemessages[1], sizeof(writemessages[1])); usleep(1);

}

return 0;

}

Алгоритм

Шаг 1 - Создать pipe.

Шаг 2 - Создать дочерний процесс.

Шаг 3 - Родительский процесс пишет в pipe.

Шаг 4 - Дочерний процесс извлекает сообщение из pipe и записывает его в стандартный вывод.

Шаг 5 - Повторите шаг 3 и шаг 4 еще раз.

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

В данной программе используется только один pipe для односторонней передачи данных, поэтому: либо родительский процесс записывает, либо дочерний процесс читает.

Покажем применение двухстороннего pipe для одновременной записи и чтения обоими процессами.

Исходный код

#include<stdio.h>

#include<unistd.h>

int main() {

int pipefds1[2], pipefds2[2];

int returnstatus1, returnstatus2; int pid;

char pipe1writemessage[20] = "Hi"; char pipe2writemessage[20] = "Hello"; char readmessage[20];

returnstatus1 = pipe(pipefds1);

if (returnstatus1 == -1) { printf("Unable to create pipe 1 \n"); return 1;

}

returnstatus2 = pipe(pipefds2);

if (returnstatus2 == -1) { printf("Unable to create pipe 2 \n"); return 1;

}

pid = fork();

if (pid != 0) { close(pipefds1[0]); close(pipefds2[1]);

printf("In Parent: Writing to pipe 1 – Message is %s\n", pipe1writemessage);

write(pipefds1[1], pipe1writemessage, sizeof(pipe1writemessage)); read(pipefds2[0], readmessage, sizeof(readmessage));

printf("In Parent: Reading from pipe 2 – Message is %s\n", readmessage); } else {

close(pipefds1[1]); close(pipefds2[0]);

read(pipefds1[0], readmessage, sizeof(readmessage));

printf("In Child: Reading from pipe 1 – Message is %s\n", readmessage); printf("In Child: Writing to pipe 2 – Message is %s\n",

pipe2writemessage);

write(pipefds2[1], pipe2writemessage, sizeof(pipe2writemessage));

}

return 0;

}

Алгоритм

Шаг 1 – Создать два pipe. Сначала родитель должен писать, а ребенок читать, скажем, через pipe1. Во-вторых, ребенок должен писать, а родитель - читать, скажем, через pipe2.

Шаг 2 - Создать дочерний процесс.

Шаг 3 - Закрыть нежелательные концы, так как для каждого сеанса связи необходим только один конец.

Шаг 4 - Закрыть нежелательные концы в родительском процессе, конец для чтения в pipe1и конец для записи в pipe2.

Шаг 5 - Закрыть нежелательные концы в дочернем процессе, конец для чтения в pipe1 конец для записи в pipe2.

Шаг 6 - Выполнить сообщение процессов как требуется.

Наиболее точно данное действо иллюстрирует следующая обобщённая схема:

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

Сначала родительский процесс записывает сообщение в первый pipe, затем он ожидает чтения сообщения, которое должен записать дочерний процесс. А дочерний процесс сначала считывает сообщение родителя “Hi” из конца read (pipefds1[0]), затем записывает своё сообщение в конец write (pipefds2[1]); когда родительский процесс обнаруживает в файловом дескрипторе pipefds2[0] запись, тотчас же выводит её в стандартный поток.

Итак: pipe file descriptors – вектор дескрипторов. pipefds1[0] – чтение, pipefds1[1] – запись. Родитель записывает только в pipefds1[1]. Ребёнок читает только из pipefds1[0].

pipefds2[0] – чтение, pipefds2[1] – запись. Ребёнок записывает только в pipefds2[1]. Родитель читает только из pipefds2[0].

Системный вызов функции pipe() заставляет операционную систему Linux инициализировать pipepfsX дескриптором из таблицы сигнальных переменный процесса, например 3 и 4, причём тех, которые не используются.

Выводы:

Врезультате мы достигли следующего:

1.Научились работать с процессами в системе Linux, также применили знания для написания программы;

2.Повторили материал по потокам ввода-вывода, стандартным конструкциям языка C++;

3.Использовалиpipe вдлявзаимодействияпроцессовчерезсистемныйвызов ОС Linux.