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ó