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

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

.docx
Скачиваний:
40
Добавлен:
20.02.2019
Размер:
76.97 Кб
Скачать

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

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

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

(СПбГУТ)

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

Отчёт

по лабораторной работе №7 на тему: «Разработка приложений под Linux»

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

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

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

Принял: __к.т.н. Дагаев А.В.

« » 2018 г. ___________/_А.В. Дагаев/

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

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

Исходный код

//пример 1

#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 для одновременной записи и чтения обоими процессами.

Исходный код

//пример 2

#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.

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