ФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА»
(СПбГУТ)
ОТЧЁТ
по лабораторной работе №7 на тему: «Разработка приложений под Linux»
по дисциплине «Операционные системы»
Выполнили: студенты группы ИКВТ-61, Миронов П.В., Гарифулина Т.С.
Принял: доцент кафедры ПИиВТ Дагаев А.В.
Цель: разработать приложение использующее несколько процессов и объекты синхронизации под linux.
Средства: Для выполнения данной работы использовались: утилита для постановки виртуальной машины Oracle VM, дистрибутив Ubuntu 16.0.4, CodeBlocks.
Основные определения:
-
Мьютекс (англ. mutex, от mutual exclusion — «взаимное исключение») — аналог одноместного семафора, служащий в программировании для синхронизации одновременно выполняющихся потоков. Мьютекс отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние. Мьютексы — это один из вариантов семафорных механизмов для организации взаимного исключения. Они реализованы во многих ОС, их основное назначение — организация взаимного исключения для потоков из одного и того же или из разных процессов.
-
Примерами таких синхронизирующих объектов ОС являются системные семафоры, мьютексы, события, таймеры и другие — их набор зависит от конкретной ОС, которая создает эти объекты по запросам процессов. Чтобы процессы могли разделять синхронизирующие объекты, в разных ОС используются разные метода. Некоторые ОС возвращают указатель на объект. Этот указатель может быть доступен всем родственным процессам, наследующим характеристики общего родительского процесса. В других ОС процессы в запросах на создание объектов синхронизации указывают имена, которые должны быть им присвоены. Далее эти имена используются разными процессами для манипуляций объектами синхронизации. В таком случае работа с синхронизирующими объектами подобна работе с файлами. Их можно создавать, открывать, закрывать, уничтожать.
Теоретическая часть:
Для создания потока используется библиотека pthread и вызов pthread_create, для синхронизации в этой же библиотеке описаны специальные объекты - мьютексы. Мьютекс - это объект который может принадлежать в некий момент времени только одному потоку и имеющий два состояния - занят и свободен. Поток пытающийся получить доступ к мьютексу в случае если последний занят будет остановлен системой до освобождения объекта. На этом собственно и основана синхронизация - перед использованием общего ресурса потоки сначала обращаются к мьютексу и в конечном счете выстраиваются в очередь.
В ситуации когда есть много потоков выполняющих только чтение некоего ресурса(они не нуждаются в синхронизации между собой) и один или несколько потоков выполняющих изменение этого ресурса. Т.е. синхронизировать нужно этот пишущий поток со всеми читателями. Если просто использовать мьютекс для синхронизации доступа к ресурсу очевидно что и потоки чтения будут получать доступ туда последовательно, что в свою очередь замедлит приложение, фактически превратив его в однопоточное. В этой ситуации одним из вариантов решения будет применение семафора. Семафор - это специальный объект ядра предназначенный для взаимодействия процессов в системе. В системе создается именованное множество семафоров(содержащее минимум 1 семафор), каждый семафор содержит некое количество ресурсов выраженное целым числом. Поток может запрашивать ресурсы у семафора и естественно должен отдавать их обратно когда они более не нужны. В случае если запрошенное количество ресурсов недоступно, но меньше максимального имеющегося количества - поток ожидает освобождения(в случае если не установлена опция - без ожидания)- иначе возвращается ошибка. Таким образом семафор более гибкий механизм синхронизации(однако неприятность в том что это объект ядра)
Ход работы:
Программа pipes создает два процесса и обеспечивает двустороннюю связь между ними посредством неименованных каналов.
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream.h>
#include <strings.h>
#include <fstream.h>
#define MAXLINE 128
void server(int,int), client(int,int);
int main(int argc, char **argv) {
int
pipe1[2],pipe2[2]; // идентификаторы каналов
pid_t
childpid = 0;
printf("Parent: Creating pipes...\n");
pipe(pipe1);
pipe(pipe2);
printf("Parent: Pipes created...\n");
printf("Parent: Creating child process...\n");
if ((childpid = fork()) == 0) { // child process starts
printf("Child:
Child process created...\n");
close(pipe1[1]);
close(pipe2[0]);
printf("Child:
Starting server...\n");
server(pipe1[0], pipe2[1]);
printf("Child:
Terminating process...\n");
exit(0);
}
// parent process
close(pipe1[0]);
close(pipe2[1]);
printf("Parent:
Starting client...\n");
client(pipe2[0],pipe1[1]);
printf("Parent: Waiting for child porecess to terminate a zombie...\n");
waitpid(childpid, NULL, 0);
printf("Parent: Zombie terminated...\n");
return 0;
}
void server(int readfd, int writefd) {
char str[MAXLINE];
strcpy(str,"some string to transmit");
ssize_t n = 0;
printf("%s %s %s","Child:
Server: Tranferting string
to client - \"",str,"\"\n");
write(writefd, str, strlen(str));
printf("Child:
Server: Waiting for replay from client...");
while ((n = read(readfd,str,MAXLINE)) > 0)
{
str[n] = 0;
printf("%s %s %s","Received OK from client - \"",str,"\"\n");
break;
}
printf("Child:
Server was terminated...\n");
return;
}
void client(int readfd, int writefd) {
ssize_t n = 0;
char buff[MAXLINE];
while ((n = read(readfd, buff, MAXLINE)) > 0 )
{
buff[n] = 0;
printf("%s %s %s","Client: Recieved string from server: \"",buff,"\"\n");
break;
}
printf("Parent: Client: Sending OK to server\n");
strcpy(buff,"sends OK from client");
write(writefd, buff, strlen(buff));
return;
}
-
Результат выполнения:
Вывод: изучив теоретический материал, мы разработали приложение, которое использует несколько процессов и объектов синхронизации, создав его в CodeBlocks.
САНКТ-ПЕТЕРБУРГ 2018