Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по АК.doc
Скачиваний:
5
Добавлен:
01.05.2025
Размер:
752.64 Кб
Скачать

Разработка систем с помощью передачи сообщений.

Разработка систем с помощью передачи сообщений связано с рядом проблем:

  1. Сообщение может затеряться во время передачи. Во избежании этого отправитель и получатель договариваются о подтверждении приема. Если сообщение не получено отправитель повторяет передачу.

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

  3. Необходимо однозначно определять процесс, указываемый в запросах send и receive, что достигается с помощью механизма аутентификации.

В механизме передачи сообщений существует свое решение проблемы производителя и потребителя.

#define №100

void producer(void)

{

int item;

message m;

while(true)

{

item=produce_item();

receive(consumer, &m);

build_messag(&m, item);

send(consumer, &m);

}

}

void consummer(void)

{

int item;

message m;

for(int=0;i<N;i++)

{

send(producer, &m);

item=extract_item(&m);

send(producer, &m);

if(count==N-1)wakeup(produser);

consume_item(item);

}

}

В данном примере существуют ограничения:

  1. Все сообщения имеютодинаковый размер.

  2. Все сообщения которые посланы и не получены помещаются в ОС в буфер.

Следует учитывать что потребитель и производитель могут работать с разной скоростью. В этом случае использеутся адресуемые сообщения т.е. каждому из процессов присвоен уникальный адрес и сообщение адресуется по номерам, такой подход называют методом почтового ящика – это некоторый буфер, который просматривает процессы в поисках запросов либо сообщений для себя. При этом send и receive обмен идет между процессом и почтовым ящиком.

Существует другой подход, так называемый метод Рандегу, в этом случае процесс обменивается с процессом без буферизации. При отсутствии данных либо запросов соотвецтвующий процесс переключается на другие задачи. Подразумевается что в этом случае процессы работают примерно одинаково либо ведомый процесс производный. Поэтому ведомый процесс работает медленнее ведущего однако он способен производить данные в 2 раза чаще чем происходит значение отклонения контролируемого параметра.

Классические проблемы межпроцессорного взаимодействия.

Проблема обедающих философов.

Проблема состоит в разработке синхронизации философов.

Простое решение:

#define №5

void philosoher(int i)

{

while(true)

{

think();

take_fork(i);

take_fork((I+1)%N);

cat();

puttork(i);

put_fork((i+1)%N)

}

}

Ситуация в которой процессы могут работать скольугодно долго но не добиваться процесса называется зависанием в отличии от клинча.

Starvation – зависание.

Правильное решение:

#define №5

#define LEFT (i+N.1)%N

#define RIGHT (i+1)%N

#define THINKING 0

#define HUNGRY 1

#define EATING 2

tepedef int semaphore;

int state[N]; // массив для отслеживания состояния каждого философа.

semaphore mntex;

semaphore S[N];

void philosopher(int i)

{

while(true)

{

think();

take_forks(i);

cat();

puttork(i);

put_forks(i);

}

}

void take_forks(int i)

{

down(&utex);

state[i]=HUNGRY;

test(i);

up(&mutex);

down(&S[i]);

}

void put_forcs(int i)

{

down(&mutex);

state[I]= THINKING;

test(LEFT);

up(&mutex);

}

void test(int i)

{

if(state[i]== HUNGRY && state[LEFT]!= EATING && state[RIGHT]!=[A]Na)

{

state[i]=EATING;

}

}

Проблема читателей и писателей.

Эта проблема моделирует доступ к БД. Пускай существует БД продажи билетов на поезд, к которой одновременно пытается получить доступ множество кассиров. Необходимо разработать алгортм синхронизации позволяющий осуществлять множественный доступ к чтению и записи, при доступена запись любой доступ на чтение также должен быть запрещен.

typedef int semaphore;

semaphore mytex = 1;

semaphore db = 1;

int rc = 0;

void reader()

{

while(true)

{

down(&mutex);

rc++;

if(rc==1)down(&db);

up(&mutex);

real_data_base();

down(&mutex);

rc--;

if(rc==1)up(&db);

up(&mutex);

use_data_read();

}

}

void writer()

{

while(true)

{

think_up_data();

down(&db);

write_data_base();

up(&db);

}

}

Недостаток: в данном алгоритме писатель блокируется до того момента пока все читатели не выйдут из критической секции доступа БД. Если запросы на чтение поступают достаточно часто то писатель не сможет приступить к записи.

Есть несколько подходов:

  1. Ограничить количество запросов читателя во временном промежутке.

  2. Ввести в алгоритм дополнительные переменные блокировки, сформировав ограничение таким образом: если писатель заблокирован не один читатель не получит доступа.

  3. Постановка процессов в очередь с помощью планировщика процессов.

  4. Предоставить пишущему процессу более высокий приоритет при этом все читатели будут заблокированы ОС.

Последний подход наилучший т.к. первые 3 снижают производительность системы за счет снижения конкуренции.

Проблема спящего брадобрея.

В зале есть 1 бродобрей, кресло в котором он бреит клиентов и н-е количество стульев для очереди, если никого нет бродобрей спит. Когда в парикмахерскую заходит клиент, он должен разбудить бродобрея. Если бродобрей занят он садится в очередь, если свободных стульев нет он уходит. Необходимо создать алгоритм работы брадабрея и посетителей исключающий состояние состязания, аналог это служба обработки ограниченного количества запросов снабжения очередью из запросов.

#define CHAIRS 5

#define int semaphore;

semaphore customers=0; //очередь

semaphore barbers = 0; //количество спящих брадобреев

semaphore mutex = 1; // управление доступа в критическую секцию

int waiting = 0; // очередь посетителей в очереди

void barber()

{

while(true)

{

down(&customers);

down(&mutex);

waiting--;

up(&burbers);

up(&mutex);

cnt_hair();

}

}

void customers ()

{

down(&mutex);

if(waiting< CHAIRS)

{

waiting++;

up(&customer);

up(&mutex);

down(&borber);

get_haieut();

}

else

up(&mutex);

}

}