Az MPD programozási nyelv

Párhuzamosság

Párhuzamosság

Szintaxis

A nyelv kimondottan a párhuzamosság támogatására lett kifejlesztve, mint a neve is mutatja. Egy már ismertetett idetartozó elem az alprogramok paramétereinek visszaadási módjának precíz megválaszthatósága.

A resource-ok mûveleteit (proc/procedure) és belépési pontjait (in) lehet szinkron (call) illetve aszinkron (send) módon hívni.

Párhuzamos végrehajtást eredményez a co [ azonosító = kezdet to vég by lépésköz ] törzs oc kifejezés is, azonban ez az adott erõforrást blokkolja addig, amíg minden számítás véget nem ér benne.

Folyamatot process azonosító [ azonosító = kezdet to vég by lépésköz ] { törzs } alakban adhatunk meg; a deklaráció kiértékelésekor a folyamat elindul (az indító folyamatot nem blokkolva).

Példa : az elõbbi mátrixszorzás párhuzamosítása

global defs const int SIZE = 8 end resource matrix_mult() import defs real a[ SIZE, SIZE ] = ([SIZE] ([SIZE] 1.0)) real b[ SIZE, SIZE ] = ([SIZE] ([SIZE] 1.0)) real c[ SIZE, SIZE ] procedure inner( int i, int j ) return real sum # belsõ szorzat számítása: a[i,*] * b[*,j] { sum = 0.0; for [ k = 1 to SIZE ] { sum += a[i,k] * b[k,j] } } co [ i = 1 to SIZE, j = 1 to SIZE ] c[i,j] = inner(i,j) oc for [ i = 1 to SIZE ] # az eredmény kiírása { for [ j = 1 to SIZE ] { writes( c[i,j], " " ); } write(); # új sor } end

Példa : kritikus szakasz-szimuláció

global CS op CSenter(int id) {call}, # csak call-lal hívható CSexit() # call-lal és send-del is hívható body CS process arbitrator { while ( true ) { in CSenter( id ) by id -> write( id, " belépett kritikus szakaszába" ) ni receive CSexit() } } end resource main() import CS int numusers, rounds getarg( 1, numusers ) # parancssori paraméterek beolvasása getarg( 2, rounds ) process user[ i = 1 to numusers ] { for [ j = 1 to rounds ] { call CSenter( i ) nap( int( random() * 100 ) ) send CSexit() nap( int( random() * 1000 ) ) } } end

Példa : író-olvasó-probléma megoldása mutexszel

global DataBase op read( var int data ) # olvasás op write( val int data ) # írás body DataBase int database = 0 # egyszerû adatbázis sem rw = 1, mutexR = 1 int nr = 0 procedure startread() { P( mutexR ) nr++ if ( nr == 1 ) { P(rw) } V( mutexR ) } procedure endread() { P( mutexR ) nr-- if ( nr == 0 ) { V(rw) } V( mutexR ) } proc read( data ) { startread() nap( 500 ) data = database endread() } proc write( data ) { P( rw ) nap( 1000 ) database = data V(rw) } end resource main() import DataBase int numReaders; getarg( 1, numReaders ) int numWriters; getarg( 2, numWriters ) int rounds; getarg( 3, rounds ) process Reader[ i = 1 to numReaders ] { int myvalue nap( int( random() * 1000 ) ) # hogy minden folyamatnak legyen ideje elindulni for [j = 1 to rounds] { DataBase.read( myvalue ) write( "reader", i, "read", myvalue ) nap( int( random() * 1000 ) ) } } process Writer[ i = 1 to numWriters ] { int myvalue = i nap( int( random() * 1000 ) ) for [ j = 1 to rounds ] { DataBase.write( myvalue ) write( "writer", i, "wrote", myvalue ) nap( int( random() * 1000 ) ) } } end

Kommunikáció

Szinkronizáció