Ïàðàëëåëüíûå ïðîöåññû



  1. Äëÿ ÷åãî íóæíû ïàðàëëåëüíûå ïðîöåññû è íèòè: îïòèìèçàöèÿ, óñêîðåíèå

  2. Êàê ñîçäàåòñÿ ïðîöåññ: fork()

  3. Êàê òåðìèíèðóåòñÿ ïðîöåññ: exit(), “kill -9 <pid>”, wait(NULL)

  4. Êàê ñîçäàåòñÿ íèòü: phtread_create()

  5. Êàê òåðìèíèðóåòñÿ íèòü: a) íèòü ñîçäàíà - çàêàí÷èâàåòñÿ ôóíêöèÿ íèòè b) îñí.íèòü — return (pthread_join())

  6. Êàêèå òðóäíîñòè ó ïðîãðàììèðîâàíèÿ ïàðàëëåëüíûõ ïðîöåññîâ è íèòåé: âçàèìîäåéñòâèå, ñèíõðîíèçàöèÿ

  7. ×òî òàêîå ðàçäåëÿåìûå ðåñóðñû: îáùèå ðåñóðñû

  8. Êàêèå ðàçäåëÿåìûå ðåñóðñû ó ïðîöåññîâ: ýêðàí, êëàâèàòóðà, ôàéëû, ðàçäåëÿåìàÿ ïàìÿòü, pipe, ...

  9. Êàêèå ðàçäåëÿåìûå ðåñóðñû ó íèòåé: ýêðàí, êëàâèàòóðà, ôàéëû, îáùàÿ ïàìÿòü (ãëîáàëüíûå ïåðåìåííûå, îáùèå àäðåñà)

  10. Ìåõàíèçìû ñèíõðîíèçàöèè ïðîöåññîâ: ñåìàôîðû, ôàéëû, ðàçäåëÿåìàÿ ïàìÿòü, pipe

  11. Ìåõàíèçìû ñèíõðîíèçàöèè íèòåé: ìüþòåêñû, ñåìàôîðû



1. Ïðîöåññû: ìóëüòèçàäà÷íîñòü.

àçäåëåíèå ïðîöåññîðíîãî âðåìåíè. Êâàíò âðåìåíè. Ðåæèì îæèäàíèÿ.




Íàïîìèíàíèå:

3 ñîñòîÿíèÿ ïðîöåññà: âûïîëíåíèå, îæèäàíèå ðåñóðñà, ãîòîâ ê âûïîëíåíèþ

ÁÈÎÑ + ÎÑ

Ïðîöåññ — îñíîâíîå ïîíÿòèå ÎÑ

Îäèí ïðîöåññ ìîæåò ïîðîäèòü äðóãîé ïðîöåññ. Ðîäèòåëüñêèé → äî÷åðíèé

Ñîñòîÿíèå ïðîöåññà — ñîñòîÿíèå îáëàñòè ïàìÿòè, ñîñòîÿíèå ðåãèñòðîâ ïðîöåññîðà + ...

Ðåãèñòðû ïðîöåññîðà — PC (Program Counter), SP (Stack Pointer), ...

Àðõèòåêòóðû ïðîöåññîðîâ: RISC (Restricted Instruction Set) è EISC (Extended ...)

ARM (RISC) – 38 (16 * 2 + ...)

Ïàìÿòü (ïî ñòåïåíè óáûâàíèÿ áûñòðîäåéñòâèÿ, ïî ñòåïåíè óáûâàíèÿ ñòîèìîñòè, ïî ìåðå âîçðàñòàíèÿ îáúåìà): ðåãèñòðû ïðîöåññîðà, êýø ïàìÿòü, îïåðàòèâíàÿ ïàìÿòü, âíåøíÿÿ ïàìÿòü.

Ïðè ïåðåêëþ÷åíèè ïðîöåññîâ — ÷òî äåëàòü ñ ñîñòîÿíèåì ïðîöåññà, ÷òîáû åãî âîçîáíîâèòü. Ñîõðàíèòü. Ñîñòîÿíèå îáëàñòè ïàìÿòè — ñîõðàíÿåòñÿ àâòîìàòè÷åñêè.

Ñîñòîÿíèå ðåãèñòðîâ — íàäî ñîõðàíèòü.

Ñîçäàíèå ïðîöåññà (äî÷åðíåãî): êëîíèðîâàíèå

Ñîñòîÿíèå äî÷åðíåãî ïðîöåññà — âûäåëÿåòñÿ îáëàñòü ïàìÿòè, ñîäåðæèìîå èäåíòè÷íî ñîäåðæèìîìó ðîäèòåëüñêîãî ïðîöåññà, ñîñòîÿíèå ðåãèñòðîâ — òàêîå æå.

Ïðèìåð.

Ëèíóêñ — ñîçäàòü ïðîöåññ î÷åíü ïðîñòî: âûçâàòü ôóíêöèþ fork();

int main() {

int id;

id = fork(); /* Äëÿ ðîä.ïð. - èäåíòèôèêàòîð äî÷åðíåãî ïðîöåññà, äëÿ äî÷.ïð. - 0 */

if (id != 0) {

printf(“I am an original\n”);

} else {

printf(“I am a clone\n”);

exit(1);

}

return 0;

}

Ñèãíàëû — óáèòü (òåðìèíèðîâàòü) ïðîöåññ SIGKILL

$ ps

1090 a.exe

$ kill -9 1090

Íèòè — ïîäïðîöåññû âíóòðè ïðîöåññà. Threads – íèòè (ïîòîêè)

Çà÷åì íèòè?

1. Óñêîðåíèå ðàáîòû ïðîãðàììû — åñëè åñòü îæèäàíèå êàêîãî-òî ðåñóðñà, òî äðóãèå íèòè â ýòî âðåìÿ ìîãóò âûïîëíÿòü, íàïðèìåð, âû÷èñëèòåëüíûå äåéñòâèÿ.

2. Îïòèìèçàöèÿ ðàáîòû — ìîæíî ñîêðàùàòü âðåìÿ îæèäàíèÿ. Ïðèìåð — ñåðâåð. Äëÿ êàæäîãî êëèåíòà — îòäåëüíàÿ íèòü.

Ñòàíäàðò POSIX – pthread_create(), pthread_join()

6. Òðóäíîñòè

a) Ïðåäñòàâèòü ðàáîòó íèòåé è èõ âçàèìîäåéñòâèå

b) Ñèíõðîíèçèðîâàòü (íå àòîìàðíûé) äîñòóï ê ðàçäåëÿåìûì ðåñóðñàì



void run(void *arg);

int x=0;

pthread_t thread1, thread2;

int main() {

pthread_create(&thread1, NULL, run, NULL);

pthread_create(&thread2, NULL, run, NULL);

return 0;

}

void run(void *arg) {

++x;

}

Thread 1

R1 íèòè 1

x

R1 íèòè 2

Thread 2

LDR R1, &x;

INC R1;





STR R1, &x;

0

1

0







1

1





0

1



LDR R1, &x;

INC R1;

STR R1, &x;



Ïðàâèëüíûé îòâåò: 2.

Îòâåò íåâåðíûé, ò. ê. îïåðàöèÿ óâåëè÷åíèÿ x áûëà ïðåðâàíà íà ñåðåäèíå (íå àòîìàðíàÿ)

Âûâîä: äîñòóï ê ðàçäåëÿåìûì ðåñóðñàì íàäî ñèíõðîíèçèðîâàòü.

Ó íèòåé äëÿ ýòîãî èñïîëüçóåòñÿ ìüþòåêñ.

Mutex (âçàìîèñêëþ÷àþùèé)

Êîä, âûïîëíåíèå êîòîðîãî íåëüçÿ ïðåðûâàòü, íàçûâàåòñÿ êðèòè÷åñêàÿ ñåêöèÿ

Äëÿ òîãî, ÷òîáû èñêëþ÷èòü ïðåðûâàíèå âûïîëíåíèÿ êðèòè÷åñêîé ñåêöèè, ìîæíî îêðóæèòü åå âûçîâàìè ñëåäóþùèõ ôóíêöèé:

phtread_mutex_lock(); - âíóòðè ýòîé ôóíêöèè âûïîëíåíèå íèòè ìîæåò áûòü îñòàíîâëåíî

pthread_mutex_unlock(); - îòïóñòèòü ìüþòåêñ → âûïîëíåíèå ïðèîñòàíîâëåííîé íèòè âîçîáíîâëÿåòñÿ â ôóíêöèè phtread_mutex_lock(), ñëåäóþùàÿ ïî î÷åðåäè íèòü âûõîäèò èç ôóíêöèè è çàõîäèò â êðèòè÷åñêóþ ñåêöèþ.



Ïðèìåð ñ ìüþòåêñàìè: http://mech.math.msu.su/~nap/2/Threads/threadtst.cpp

Ïðèìåð ñ ñåìàôîðàìè: http://mech.math.msu.su/~nap/2/Threads/semExample.cpp

Ïðèìåð: 10 íèòåé äîëæíû ïî î÷åðåäè íàïå÷àòàòü ñâîé íîìåð.

Ñîçäàåì 10 ñåìàôîðîâ. Ïåðâîìó äàåò ñîñòîÿíèå 1, îñòàëüíûì 0.

Ôóíêöèÿ íèòè ìîæåò áûòü îäíà íà âñåõ.

sem_t sem[10];

void run(void *arg) {

int num = *((int*)arg);

sem_wait(&sem[num]);

print("%d\n", num);

num = (num + 1) % 10;

sem_post(&sem[num]); // Ïîäíèìàåì ñåìàôîð äëÿ ñëåäóþùåé íèòè

}

Ñåìàôîð äëÿ ïðîöåññîâ: ïðîöåññû íå âçàèìîäåéñòâóþò ÷åðåç ïàìÿòü. Îäèí è òîòò æå ñåìàôîð äëÿ ðàçëè÷íûõ ïðîöåññîâ ðàçäåëÿåòñÿ:

1) ëèáî ýòî ðîäèòåëüñêèé è äî÷åðíèé ïðîöåññû: ïîêà íå ðàçäåëèëèñü, òî ñåìàôîð îáùèé, à ïîñëå ðàçäåëåíèÿ ÎÑ ïîääåðæèâàåò ýòî âçàèìîäåéñòâèå

2) åñëè ýòî íå ñâÿçàííûå ïðîöåññû, òî ÷åðåç èìÿ ñåìàôîðà (èìåíîâàííûé ñåìàôîð).

Âçàèìîäåéñòâèå ïàðàëëåëüíûõ ïðîöåññîâ


Ïðîöåññû ìîãóò âçàèìîäåéñòâîâàòü äðóã ñ äðóãîì ÷åðåç íåêîòîðûå îáúåêòû. Äëÿ ýòîãî îíè äîëæíû âëàäåòü èíôîðìàöèåé îá ýòèõ îáúåêòàõ. Ýòà èíôîðìàöèÿ:
1) Äëÿ âçàèìîäåéñòâèÿ ÷åðåç ôàéë - èìÿ ôàéëà;

2) Äëÿ âçàèìîäåéñòâèÿ ÷åðåç ðàçäåëÿåìóþ ïàìÿòü (shared memory) - èìÿ ðàçäåëÿåìîé ïàìÿòè;

3) Äëÿ âçàèìîäåéñòâèÿ ÷åðåç èìåíîâàííóþ «òðóáêó» pipe – èìÿ òðóáêè;

4) Äëÿ âçàèìîäåéñòâèÿ ÷åðåç áåçûìÿííóþ «òðóáêó» pipe – èäåíòèôèêàòîð îòêðûòîé áåçûìÿííîé «òðóáêè».  äàííîì ñëó÷àå â ìîìåíò ñîçäàíèÿ «òðóáêè» ïðîöåññû äîëæíû èìåòü îáùåå àäðåñíîå ïðîñòðàíñòâî, òî åñòü ýòî ðîäèòåëüñêèé è äî÷åðíèé ïðîöåññû (http://mech.math.msu.su/~nap/2/Threads/pipe.cpp)

5) Äëÿ âçàèìîäåéñòâèÿ ïî ñåòè - ñåòåâîé àäðåñ è íîìåð ïîðòà ñåòåâîãî ñîêåòà;

Èñïîëüçóÿ ýòó èíôîðìàöèþ, îíè ïîëó÷àþò äîñòóï ê íåêèì îáúåêòàì. Ýòè îáúåêòû, ðàçäåëÿåìûå ìåæäó ïðîöåññàìè, ÿâëÿþòñÿ èõ ðàçäåëÿåìûìè ðåñóðñàìè.

Ðàáîòû ñ ðàçäåëÿåìûå ðåñóðñàìè äîëæíà áûòü ñèíõðîíèçèðîâàíà, òî åñòü óïîðÿäî÷åíà. Äëÿ íåêîòîðûõ îáúåêòîâ ðàáîòà ñ íèìè óïîðÿäî÷åíà íà óðîâíå ñèñòåìû: ðàçäåëÿåìàÿ ïàìÿòü, ñîêåòû, ôàéëû. Äëÿ ðàáîòû ñ äðóãèìè ðàçäåëÿåìûìè îáúåêòàìè ïðîöåññû äîëæíû èñïîëüçîâàòü ñðåäñòâà ñèíõðîíèçàöèè. Íàïðèìåð, íèòè äëÿ ðàáîòû ñ ðàçäåëÿåìûì (òî åñòü ãëîáàëüíûìè) ïåðåìåííûìè ìîãóò èñïîëüçîâàòü ìüþòåêñû èëè ñåìàôîðû.



Çàäà÷à íà ñèíõðîíèçàöèþ íèòåé:

1. Ïðîãðàììà ñîçäàåò òðè íèòè. Äâå ãëîáàëüíûå ïåðåìåííûå ñíà÷àëà ñîäåðæàò çíà÷åíèÿ -1. Ïåðâàÿ è âòîðàÿ íèòü ãåíåðèðóþò ñëó÷àéíîå öåëîå ÷èñëî â äèàïàçîíå îò 0 äî 99 è çàïèñûâàþò èõ â ýòè äâå ãëîáàëüíûå ïåðåìåííûå. Ïîñëå ýòîãî òðåòüÿ íèòü íàõîäèò ÍÎÄ ýòèõ ÷èñåë, âûâîäèò íà ýêðàí îáà ÷èñëà è èõ ÍÎÄ è çàïèñûâàåò â ãëîáàëüíûå ïåðåìåííûå -1. Çàòåì ïåðâàÿ è âòîðàÿ íèòè ñíîâà çàïèñûâàþò ñëó÷àéíûå ÷èñëà â ãëîáàëüíûå ïåðåìåííûå è òàê äî áåñêîíå÷íîñòè.

(Ïåðâûå äâå íèòè æäóò -1 â ñâîèõ ïåðåìåííûõ, ïîòîì çàïèñûâàþò ñëó÷àéíûå ÷èñëà.

Òðåòüÿ íèòü æäåò >= 0 â îáåèõ ïåðåìåííûõ.)

(Ñèíõðîíèçèðóåòñÿ èçìåíåíèå ïåðåìåííûõ).

2. Ïðîãðàììà ñ÷èòûâàåò ñ êëàâèàòóðû äâà öåëûõ ÷èñëà, ïîìåùàåò èõ â äâå ãëîáàëüíûå öåëûå ïåðåìåííûå è âû÷èñëÿåò èõ ÍÎÄ ñëåäóþùèì îáðàçîì: äâå íèòè âû÷èòàþò èç áîëüøåãî ÷èñëà ìåíüøåå: ïåðâàÿ íèòü âû÷èòàåò èç ïåðâîé ïåðåìåííîé, âòîðàÿ — èç âòîðîé ïåðåìåííîé. Ïîñëå íàõîæäåíèÿ ÍÎÄ (òî åñòü êîãäà îáå ïåðåìåííûå ïðèíèìàþò îäèíàêîâîå çíà÷åíèå) íèòè çàêàí÷èâàþò ðàáîòó è ÍÎÄ âûâîäèòñÿ íà ýêðàí.

(Ìüþòåêñ çàõâàòûâàåòñÿ êàê äëÿ ïðîâåðêè çíà÷åíèÿ ïåðåìåííîé (???), òàê è äëÿ èçìåíåíèÿ çíà÷åíèÿ ïåðåìåííîé).