Transcript void

Дәріс Семафорлар (Semaphores)

  Параллельді есептеулерді қамтамасыз ететін ОЖ механизмдері және программалау тілдері.

Фундаментальді принцип –   2 және оданда көп процесстер бір-бірімен жәй сигналдар арқылы қызметтес болады Белгілі орында процесс жұмысын тоқтата алады тек белгілі бір сигналды алғанға дейін

Семафорлар

   signal(s) –семафор арқылы сигнал беру үшін wait(s) –сигнал алу үшін Семафор – бүтін типті арнайы айнымалы    Инициализация оң мәндермен wait() операциясы семафор мәнін азайтады. Егер семафор мәні < 0 болса, онда процесс бұғатталады.

signal() операциясы семафор мәнін көбейтеді. Егер семафора мәні <=0, онда бір процесс, wait() операциясынды бұғатталған болса ол қайт ашылады.

struct

semaphore {

int

count; }

queueType

queue; { void wait(semaphore s) s.count--; } {

if

(s.count < 0) place this process in s.queue; block this process } void signal(semaphore s) { s.count++; } } {

if

(s.count <= 0) remove a process P from s.queue; place process P on ready list;

мысал

/*

program

mutualexclusion */

const int

n = /* number of processes */;

semaphore

s = 1; { void P(

int

i) {

while

(true) wait(s); /* critical section */; signal(s); } /* remainder */; } { void main() }

parbegin

(P(1), P(2), . . ., P(n));

Mutual Exclusion Using Semaphores

Семафорлар

   Бинарлы семафор: 0 или 1 Күшті семафор:  Кезектегі процесстерден процесстердің ретпен алынуы, күту семафорлары, ол FIFO (first-in first-out) Әлсіз семафор  процесстердің кезектен ретпен алынуы анықталмаған

struct

binary_semaphore {

enum

(zero, one) value;

queueType

queue; }; {

void

waitB(binary_semaphore s)

if

(s.value == 1) s.value = 0; {

else

place this process in s.queue; } block this process; }

void

signalB(semaphore s) {

if

(s.queue.is_empty()) s.value = 1;

else

} { remove a process P from s.queue; } place process P on ready list; Бинарлы семафор

Өндіруші/тұтынушы есебі

Producer/Consumer Problem

   1 немесе одан көп өндірушілер деректерді генерациялайды (жазбалар, символдар және т.б.) және оларды буферге орналастырады Жалғыз өндіруші буфердегі элементтерді бір-бірден шығарып алады.

Талап қойылады: дәл осы уақытта тек 1 ғана өндіруші немесе 1 ғана тұтынушы буферге қатынай алады

Өндіруші

while (true) { /* производство элемента v */ b[in] = v; in++; }

тұтынушы

while (true) { while (in <= out) /*бездействие */; w = b[out]; out++; /* потребление w */ }

Буфер шексіз онда сызықты массив орналасқан

b[1] b[2] b[3] b[4] b[5] . . .

out in Рис. өндіруші/тұтынушы есебінің шексіз буфері

В-семафоры арқылы қате шешім

/*

program

producerconsumer */

int

n; binary_semaphore s = 1; binary_semaphore delay = 0; {

void

producer() {

while

(true) produce(); waitB(s); append(); n++;

if

(n==1) signalB(delay); signalB(s);}} {

void

consumer() waitB(delay);

while

(true) { waitB(s); take(); n--; signalB(s); consume();

if

(n==0) waitB(delay); }}

void

main() { n = 0;

parbegin

(producer, consumer);}

{ {

В-семафорлары арқылы дұрыс шешу

/*

program

producerconsumer */

int

n; binary_semaphore s = 1; binary_semaphore delay = 0;

void

producer()

while

(true) produce(); waitB(s); append(); n++;

if

(n==1) signalB(delay); signalB(s); } } {

void

consumer()

int

m; /* a local variable */ waitB(delay); {

while

(true) waitB(s); take(); n--; m = n; signalB(s); consume(); }

if

(m==0) waitB(delay); }

void

main() { n = 0;

parbegin

(producer, consumer);}

В-семафорлары арқылы дұрыс шешу

/*

program

producerconsumer */ semaphore n = 0; semaphore s = 1;

void

producer() {

while

(true) { produce(); wait(s); append(); signal(s); signal(n); }} {

void

consumer()

while

(true) { wait(n); wait(s); take(); signal(s); { } consume(); }

void

main() }

parbegin

(producer, consumer);

Буфер циклдық қор сақтау түрінде Бұғаттау Бұғаттауды шешу

Өндіруші:

Толық буферге қою

Тұтынушы:

Бос буферден өшіру

Өндіруші :

Толық буферге қою

Тұтынушы :

Бос буферден өшіру

Буфер циклдық қор сақтау түрінде

Өндіруші: while (true) { /* производство элемента v */ while ((in + 1) % n == out) /* бездействие */; b[in] = v; in = (in + 1) % n }

Буфер циклдық қор сақтау түрінде

тұтынушы

while (true) { while (in == out) /* бездействие */; w = b[out]; out = (out + 1) % n; /* потребление элемента w */ }

Ақырғы циклдық буфер

/*

program

boundedbuffer */

const int

sizeofbuffer = /* buffer size */; { semaphore s = 1; semaphore n= 0; semaphore e= sizeofbuffer;

void

producer() } {

while

(true) produce(); wait(e); wait(s); append(); signal(s); } signal(n) {

void

consumer()

while

(true) { wait(n); wait(s); take(); signal(s); } } signal(e); consume();

void

main() } {

parbegin

(producer, consumer);

Семафорды іске асыру

 wait and signal атомарлы орындалуы тиіс    аппараттық қамтамасыз етуде іске асырылуы мүмкін Программалық схеманы қолдануы мүмкіны  Бұл қосымша шығынға келуі мүмкін Аппараттық деңгейдегі ӨТ схемасын қолдануы мүмкін

wait(s) {

while (!

testset(s.flag)) /* do nothing */; s.count--; {

if

(s.count < 0) place this process in s.queue; block this process (must also set s.flag to 0) }

else

s.flag = 0; } signal(s) {

while (!

testset(s.flag)) /* do nothing */; s.count++; {

if

(s.count <= 0) } remove a process P from s.queue; place process P on ready list s.flag = 0;}

(a) Testset Instruction

{ wait(s) inhibit interrupts; s.count--;

if

(s.count < 0) { place this process in s.queue; } block this process and allow interrupts

else

allow interrupts;} signal(s) { inhibit interrupts; s.count++;

if

(s.count <= 0) { remove a process P from s.queue; } place process P on ready list allow interrupts;}

(b) Interrupts

Шаштараз туралы есеп

(Barbershop Problem)

Семафорларды қолдану күрделілігі

 wait and signal операциялары программада әр жерге шашырап орналасқан болуы мүмкін, олардың семафорға әсерін байқау қиын

Мониторлар (Monitors)

 Монитор - программалау тілінің конструкциясы  Программалаудың көптеген тілдері арқылы жүзеге асырылған (Modula-2, Java)  Программалық кітапханалар түрінде іске асырылған

Мониторлар. Олардың негізгі характеристикасы

    М – программалық модуль:    Тізбекті инициализациялаушы 1 немесе 1 неше процедуралар Локальды деректер Локальды айнымалыларына тек монитор процедуралары қатынай алады Процесс мониторға өзінің бір процедурасын шақыру арқылы кіре алады Мониторда белгілі бір уақытта тек бір ғана процесс орындалады; келесі процесс кезегін күтеді

Мониторлар сигналдарымен

   Синхронизация үшін операциялар : cwait(c):   С шарты бойынша шақырылған процесс орындалуы тоқтата тұрады Монитор бұл уақытта басқа процесстер орындалуына қолданылып жатады csignal(c):    Соынмен бірге кейбір шақырылып cwait шарты бойынша тоқтатылған процесстер жаңарады және орындала бастайды Егер осы сияқты процесстер көп болса олардың біреу ғана таңдалынады. Егер процесстер жоқ болса, функция еш нәрсе жасамайды.

Монитор құрылымы

Өндіруші/тұтынушы есебіне мысал

    Монитордың жалғыз ғана ену нүктесі болады Мониторға енген процесс уақытша cwait(х) шақырып тоқтатыла тұрады Мониторда орындалып жатқан процессі х айнымалысында өзгерісті кездестірсе, онда ол кезектің өзгергенін хабарлайтын csignal(х) операциясын орындайды.

Монитор екі айнымалы шарт қояды:   notfull болса ақиқат, егер буферде минимум символаға орын n otempty – егер буферде ең құрғанда 1 символ болса

/* program

producerconsumer */

monitor

boundedbuffer;

char

buffer [N]; /* Место для N элементов */

int int

nextin, nextout; count;

/*

указатели буфера */

/*

количество элементов в буфере */

int

notfull, notempty;

/*

Синхронизация */ {

void

append (char x)

if

(count == N) cwait(notfull); /* Буфер заполнен */ } buffer[nextin] = x; nextin = (nextin + 1)

%

N; count++; /* добавляем элемент в буфер */ csignal(notempty); /* возобновление работы потребителя */

{

void

take (char x)

if

(count == 0) cwait(notempty); /* Буфер пуст */ x = buffer[nextout]; } nextout = (nextout + 1)

%

N; count- ; /* Удаляем элемент из буфера */ csignal(notfull); /* Возобновляем работу производителей */ {

/*

Тело монитора */ nextin = 0; } nextout = 0; count = 0; /* Изначально буфер пуст */

{ { } }

void char

producer() x;

while

(true) produce(x); append(x);

void

consumer() {

char

x; } {

while

(true) } take(x); consume(x); {

void main()

}

parbegin

(producer, consumer);

Хабарлама жіберу

(Message Passing)

  Өзара тоқтатулар орындалуын қамтамасыз ету үшін синхронизация Процессорлармен ақпарат алмасу үшін байланыс

send (получатель, сообщение) receive (отправитель, сообщение)

Синхронизация

  Хабарлама алатын және жіберетін процесстер бұғатталған немесе жұмысын жасап жатуы болуы мүмкін Бұғатталған жіберу, бұғатталған хабарлама алушы   Хабарлама жетпейінше екеуіде бұғатталады Рандеву деп аталады (rendezvous)

Синхронизация

  бұғатталмаған жіберу, бұғатталған хабарлама алу   Жіберуші жұмысын жалғастыра береді Алушы хабарлама алғанша бұғатталады бұғатталмаған жіберу, бұғатталмаған хабарлама алу

Адрестеу

 Тура адрестеу  send примитиві алушы процессінің идентификаторын қосады  receive примитиві – мұнда процесс алдын-ала қай процесстен хабарлама алатынын біледі

Адрестеу

 Жанам адрестеу  Уақытша сақталынып тұрып және кезекте тұрыған хабарлама ортақ қолданылатын деректер құрылымымен жіберіледі  Кезектер почталық жәшіктер жеп аталады mailboxes

Косвенная связь между процессами

Хабарлама форматы

Обобщенный формат сообщений

Оқырмандар/жазушылар есебі

Readers/Writers Problem

    Процесстерде қолданылып жатқан деректер бар Деректер файлда болуы мүмкін. Олар процессордың регистрінде болады.

Тек деректерді оқитын бірнеше процесстер болады (оқырман) тек деректерді жазатын бернеше процесстер болады (жазушы)

Оқырмандар/жазушылар есебі

   Көптеген оқырмандар бір мезгілде бір файлдан оқуы мүмкін Файлға белгілі уақытта бір ғана жазуша жаза алады Жазушы файлға деректер жазып жатқанда бірде бір оқырман оны оқи алмайды