o program

Transkrypt

o program
Programowanie Współbieżne
PVM - wstęp
Literatura
Głównie informacje w sieci:
http://www.csm.ornl.gov/pvm/pvm_home.html - strona
główna pvm
● http://hector.tu.kielce.pl/pp/strona_pvm/index.htm tłumaczenie studentów dokumentacji do PVM
● Książki związane z tematyką przetwarzania
równoległego i rozproszonego
● Google :)
●
2
Historia
●
Idea meta-komputera
●
Wiele nowych języków czy systemów
–
●
Linda, Express, P4, OpenMosix, MPI, PVM
Prace nad PVM zaczęte w 1989 Oak Ridge
National Laboratory.
3
Cechy
●
●
●
●
Parallel Virtual Machine, jest to zestaw
programów i bibliotek systemowych dający
użytkownikowi możliwość połączenia grupy
komputerów w jeden komputer wirtualny.
Połączenia są dla użytkownika przeźroczyste
PVM jest środowiskiem heterogenicznym,
może łączyć komputery o różnej architekturze
sprzętowej jak i softwarowej, różne formaty
danych, szybkości, obciążenia maszyn i sieci.
Pozwala tanim kosztem zbudować na bazie
istniejącej sieci jeden duży multikomputer.
4
Zalety
●
●
Koszt tworzenia PVM na bazującym sprzęcie
jest znikomy.
Można zoptymalizować obliczanie dobierając
odpowiednie zadania do odpowiednich maszyn
●
Łatwa skalowalność
●
Spora dostępność
●
Łatwość instalacji
●
●
Tolerancja na błędy (istnieją funkcje
sygnalizujące różne zdarzenia)
Heterogeniczność
5
Wady
●
●
Niewielka ilość wbudowanych metod
synchronizacji procesów
Potrzeba kompilować program na każdy host z
osobna
6
Modele obliczeń
●
●
●
●
PVM opiera się na założeniu że aplikacja
składa się z kilku zadań
Każde zadanie jest odpowiedzialne za część
rachunkową obciążającą aplikację
Czasami aplikacja jest równoległa ze względu
na funkcje (np. Wprowadzanie, obliczenia,
wyprowadzanie wyników) równoległość
funkcjonalna
Najczęściej stosowanym modelem jest
równoległość danych. Te same procesy
obliczają różne porcje danych.
7
Szybki start - instalacja
●
●
Większość dystrybucji linuxowych ma pakiet pvm i pvm-gui
lub też xpvm.
Jeżeli zajdzie potrzeba można ściągnąć z
http://www.netlib.org/pvm3/index.html
●
Rozpakować tar xvf pvm3.4.4.tar
●
Ustawić zmienne środowiskowe
●
●
●
PVM_ROOT – katalog w którym zainstalowano PVM
PVM_ARCH – określa platformę sprzętową na której
środowisko zostało zainstalowane, można ustalić
automatycznie przez program inicjujący.
Wykonać make
8
Szybki start - konfiguracja
●
●
●
Użytkownik powinien posiadać konta na maszynach
które chce włączyć do środowiska PVM
PVM używa protokołu RSH do uruchamiania
demonów, można też ręcznie lub przez SSH.
w katalogu domowym użytkownika powinien być plik
konfiguracyjny .rhosts w którym to umieszcza się
nazwy / adresy komputerów z których można się
zalogować za pośrednictwem rsh bez podawania
hasła. Plik ten powinien mieć uprawnienia 400
(rw-------)
9
Szybki start - konfiguracja
SSH
●
mkdir ~/.ssh; chmod 700 ~/.ssh; cd ~/.ssh; sshkeygen -t rsa -f id_rsa -P "";cp id_rsa.pub
authorized_keys (lub cat id_rsa.pub >>
authorized_keys)
(stworzenie kluczy prywatnych i publicznych)
●
export PVMNETSOCKPORT=40000
(ustawienie minimalnego portu UDP do bezpośredniej
komunikacji)
●
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p
tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p
udp --dport 40000:45000 -s 81.26.7.128/25 -j ACCEPT
(ustawienia iptables )
10
Szybki start - konfiguracja
●
●
●
PVM_ROOT powinien być ustawiony
niezależnie dla każdej maszyny.
Przy niewłaściwym zakończeniu zostaje w
katalogu /tmp plik pvmd.<uid> , który jest
używany do autoryzacji i powinien istnieć tylko
wtedy gdy demon pvmd działa. Może to być
powodem nie uruchomienia się demona.
w pliku /tmp/pvml.<uid> znajdują się logi
uruchomienia demona
11
Szybki start - konfiguracja
●
●
pliki uruchamialne powinny być w katalogu
PVM_PATH
Przy dodawaniu hostów może wystąpić
problem gdy w pliku /etc/hosts mamy wpis typu:
127.0.0.1 localhost localhost.localdomain
nazwa_hosta
–
powinien być adres hosta lokalnego a nie jego
loopback
12
Zmienne środowiskowe
●
PVM_ROOT – ścieżka gdzie zainstalowany jest PVM
●
PVM_ARCH – architektura systemu
●
●
●
PVM_TMP – tu umieszczane są pliki pvml.<uid> i
pvmd.<uid>
PVM_RSH – ścieżka do rsh jeżeli jest gdzie indziej niż
zdefiniowano w $PVM_ROOT/conf/
$PVM_ARCH.def Można też określić by zamiast rsh
używano ssh.
PVM_PATH – ścieżka gdzie powinny się znajdować
uruchamialne pliki naszych programów, domyślnie jest
to: $HOME/pvm3/bin/$PVM_ARCH oraz
13
$PVM_ROOT/bin/$PVM_ARCH
Zmienne środowiskowe
●
●
●
PVM_WD – ścieżka robocza uruchamianych
programów
PVM_EXPORT – nazwy zmiennych do
wyeksportowania od rodzica do dziecka przy
pvm_spawn()
PVMHOSTFILE – położenie pliku hostfile,
opisującego hosty które mają wejść w skład
maszyny wirtualnej.
14
Konsola PVM
●
add – dodanie hosta
●
alias – definiowanie listy komend
●
conf - sprawdzenie aktualnej konfiguracji maszyny
wirtualnej
●
echo - wyświetla podany parametr;
●
delete – usunięcie hosta
●
halt – zatrzymanie PVM
●
help – pomoc
●
id - wyświetla ID zadań konsoli
●
jobs - wyświetla działające zadania
15
Konsola PVM
●
kill – usunięcie procesu o podanym identyfikatorze tid
●
mstat - wyświetla informacje o danym hoście
●
ps –a – pokazanie procesów w maszynie PVM
●
pstat - wyświetla informacje o danym zadaniu;
●
●
quit – wyjście z konsoli PVM (ale nie zatrzymanie tak
jak w przypadku halt)
reset - usunięcie wszystkich procesów z maszyny
PVM
●
setenv – wyswietlenie aktualnych zmiennych
●
sig - wysyła określony sygnał do określonego zadania16
Konsola PVM
●
spawn – uruchomienie procesów
–
count - liczba zadań, domyślnie 1;
–
host - uruchamia host'a; domyślnie jakikowiek;
–
ARCH - uruchamia host o danej architekturze;
–
? - aktywuje debug'owanie;
–
-> przekierowuje strumień wyjściowy zadania na konsolę;
–
-> plik przekierowuje strumień wyjściowy zadania do pliku;
–
->> plik j.w tylko że dopisuje się do pliku;
–
@ - śledzi zadanie, wyświetlając informacje na konsoli;
–
@plik - j.w tylko zapisuje do pliku;
17
Konsola PVM
●
trace - wyświetla lub ustawia opcje śledzenia
zadań;
●
unalias - deaktywuje aliasy poleceń;
●
version - wyświetla aktualną wersję PVM
18
Pierwszy program
#include<stdio.h>
#include<pvm3.h>
int main(int argc, char *argv[])
{
int myId, parentId, taskNo, tIds[3], i;
char bufor[1024];
myId = pvm_mytid();
printf("[%x] startuje\n", myId);
19
Pierwszy program
if (PvmNoParent == (parentId = pvm_parent()))
{
pvm_catchout(stdout);
printf("[%x] tworze dzieci\n", myId);
if (0 >= (taskNo = pvm_spawn("pogadanka", (char**) NULL,
PvmTaskDefault, "", 3, tIds)))
{
printf("[%x] nie moge stworzyc dzieci\n", myId);
pvm_perror("pvm_spawn");
pvm_exit();
return 1;
}
printf("[%x] stworzylem pomyslnie %i procesy\n", myId, taskNo);
for(i=0; i<taskNo; i++)
{
printf("Dziecko nr %i, Tid: %x\n", i, tIds[i]);
pvm_initsend(PvmDataDefault);
pvm_packf("%s", "Czesc, dzialasz ?");
pvm_send(tIds[i], i+1);
}
}
20
Pierwszy program
else
{
int bajtow, msgTag, tId, bufId;
printf("[%x] Dziecko: moj rodzic %x\n", myId, parentId);
bufId = pvm_recv(parentId, -1);
pvm_bufinfo(bufId, &bajtow, &msgTag, &tId);
printf("Wiadomosc ma %i bajty, id: %x; tid nadawcy: %x\n",
bajtow, msgTag, tId);
pvm_unpackf("%s", bufor);
printf("%s\n", bufor);
}
pvm_exit();
return 0;
}
21
Kompilacja
gcc –L/$PVM_ROOT/lib/$PVM_ARCH –I$PVM_ROOT/include
program.c –o program –lpvm3
Jeżeli użyjemy funkcji z group servera powinniśmy jeszcze dolinkować
pvmg3
gcc –L/$PVM_ROOT/lib/$PVM_ARCH –I$PVM_ROOT/include
program.c –o program –lpvm3 -lgpvm3
Przy kompilacji w systemie solaris należy dodać jeszcze opcje
–lnsl –lsocket
22
instalacja
Plik wykonywalny powinien trafić do katalogów
$PVM_PATH na wszystkich komputerach
wchodzących w skład PVM. Pewnym ułatwieniem
będzie tu wspólny system plików np. NFS
23
instalacja
LINUX I386
LINUX I386
LINUX I386
program
program
program.c
program
LINUX 64
LINUX 64
program.c
program
program
24
instalacja
LINUX I386
LINUX I386
LINUX I386
LINUX I386
LINUX I386
program.c
LINUX I386
program
NFS
25
Plik hostfile
●
●
●
●
●
Zawiera informacje o komputerach, które
tworzą maszynę wirtualną.
W pojedynczych wierszach umieszczone są
nazwy hostów.
Puste linijki są ignorowane
Wiersze rozpoczynające się od znaku # są
traktowane jako komentarz.
Oprócz nazw hostów może zawierać parametry
opcjonalne.
26
Plik hostfile
●
●
lo – identyfikator użytkownika
so =pw to ustawienie powoduje, że użytkownik jest proszony o
podanie hasła w celu uruchomienia demona pvmd na zdalnym
komputerze.
●
dx = lokalizacja demona pvmd
●
ep – lokalizacja aplikacji użytkownika
●
sp – wartość określającą domyślną szybkość hosta 1..1000000
(szybkość ta jest względna, podawana w celach orientacyjnych)
●
bx - lokalizacja debuggera, domyślna to $PVM_ROOT/lib/debugger
●
wd – katalog roboczy domyślnie $HOME
●
ip – nazwa hosta (umożliwia podanie alternatywnej nazwy hosta)
●
so = ms ten parametr umożliwia ręczne uruchomienie demona pvmd
27
na zdalnym komputerze.
Przykładowy hostfile
# Linie komend zaczynające się od # (ignorowane)
gstws
ipsc dx=/usr/geist/pvm3/lib/I860/pvmd3
ibm1.scri.fsu.edu lo=gst so=pw
# nadaj ustawienia domyślne następującym hostom z *
* ep=$sun/problem1:~/nla/mathlib
sparky
#azure.epm.ornl.gov
midnight.epm.ornl.gov
# zastąp opcje domyślne nowymi wartościami
* lo=gageist so=pw ep=problem1
thud.cs.utk.edu
speedy.cs.utk.edu
# maszyny do późniejszego dodania &
# istnieje tylko potrzeba listingowania opcji potrzebnych
&sun4
ep=problem1
&castor dx=/usr/local/bin/pvmd3
&dasher.cs.utk.edu lo=gageist
&elvis dx=~/pvm3/lib/SUN4/pvmd3
28
Demon pvmd
Do podstawowych funkcji demona PVM należą:
zarządzanie procesami
● wykrywanie błędów
●
29
Start pvmd
pvmd uruchomiony „ręcznie” konfiguruje się
jako demon główny (master),
● Jeśli był uruchomiony przez głównego wówczas
przyjmuje konfigurację od niego i występuje
jako demon potomny (slave).
● Tworzy socket, przez który będzie komunikował
się z innymi demonami.
● Tworzy log. /tmp/pvml.<uid>
● jeśli jest master odczytuje plik konfiguracyjny,
hostfile.
● Po zakończeniu procedury startowej demon
przechodzi w stan oczekiwania na nadejście
30
wiadomości lub zadania do wykonania
●
pvmd - zakończenie pracy
zatrzymanie demona pvmd następuje w
przypadku:
● usunięcia go z maszyny wirtualnej
● utraty połączenia z innymi demonami
● wystąpienia błędu w systemie.
31
pvmd – zakończenie pracy
Podczas zatrzymania
demon zatrzymuje wszystkie zadania uruchomione
przez siebie.
● Następnie wysyła sygnał do pozostałych węzłów
informujący o zakończeniu przez niego pracy.
● Jeżeli wysłanie do pozostałych węzłów sieci
komunikatu o zakończeniu pracy jest niemożliwe, to
powiadomieniem o wyłączeniu tego hosta zajmuje się
demon główny.
●
32
Komunikacja
●
●
●
●
Funkcje nadawcze synchroniczne typu blokującego– blokują
nadawanie procesu do momentu zakończenia nadawania
komunikatu
Funkcje odbiorcze typu blokującego i nie blokującego –
wstrzymują wykonanie procesu w oczekiwaniu na odbiór
komunikatu kreślonego typu lub umożliwiają jego odbiór
prowadząc „nasłuch” w tle przy działającej aplikacji
Komunikaty opatrzone są parą liczb całkowitych: tid i tag
Dzięki etykiecie istnieje możliwość filtrowania komunikatów przy
ich odbiorze
●
Zamiast tag lub tid przy odbiorze można użyć wildcard (-1)
●
Komunikaty są buforowane po stronie odbiorczej
●
Zagwarantowane jest zachowanie kolejności komunikatów w
kanale
33
tid
S
G
31
●
●
●
●
30 29
H
L
18
17
0
Pierwsze 0..17 L – lokalny identyfikator zadania dostępne jest 218
–1 = 262143 zadań na jednego hosta, 0 oznacza lokalny pvmd, w
UNIXie pole L jest mapowane przez pvmd na PID
H 18..29 numer hosta. Maksymalna liczba hostów 212-1=4095.
Numer 0 oznacza lokalny pvmd.
G 30 – używany w multicaście do oznaczania grup procesów.
S 31 – Zaszłość historyczna w połączeniu z h używany był do
adresowania demonów pvmd.
34
Wysyłanie komunikatu
●
Inicjacja bufora
●
Pakowanie
●
Wysłanie
35
Odebranie komunikatu
●
Odebranie
●
Rozpakowanie
36
Zarządzanie buforami
int pvm_mkbuf(int encoding) – Tworzy nowy bufor wiadomości.
Zwraca identyfikator bufora
encoding – określa sposób kodowania w buforze
● PvmDataDefault 0 kodowanie w formacie XDR
● PvmDataRaw
1 bez kodowania
● PvmDataInPlace 2 dane pozostają w miejscu.
int pvm_freebuf(int bufid) – zwolnij bufor wiadomości.
Jeśli zwróci wartość mniejszą od zera znaczy błąd
int pvm_getrbuf(void) – zwraca identyfikator aktywnego bufora komunikatów
do odbierania
int pvm_getsbuf(void) – zwraca identyfikator aktywnego bufora komunikatów
do wysyłania.
int pvm_setsbuf(int bufid) - ustawia identyfikator aktywnego bufora komunikatów
do wysyłania, zwraca poprzedni bufor
int pvm_setrbuf(int bufid) – ustawia identyfikator aktywnego bufora komunikatów
do odbierania zwraca poprzedni bufor
int pvm_inistsend(int encoding) - tworzy bufor o określonym kodowaniu,
zwraca jego identyfikator. (kodowanie jak w pvm_mkbuf)
37
Funkcje pakujące
int info = pvm_packf( const char *fmt, ... )
int info = pvm_pkbyte( char *xp, int nitem, int stride )
int info = pvm_pkcplx( float *cp, int nitem, int stride )
int info = pvm_pkdcplx( double *zp, int nitem, int stride )
int info = pvm_pkdouble( double *dp, int nitem, int stride )
int info = pvm_pkfloat( float *fp, int nitem, int stride )
int info = pvm_pkint( int *ip, int nitem, int stride )
int info = pvm_pkuint( unsigned int *ip, int nitem, int stride )
int info = pvm_pkushort( unsigned short *ip, int nitem, int stride )
int info = pvm_pkulong( unsigned long *ip, int nitem, int stride )
int info = pvm_pklong( long *ip, int nitem, int stride )
int info = pvm_pkshort( short *jp, int nitem, int stride )
int info = pvm_pkstr( char *sp )
Pierwszy parametr to wskaźnik do pierwszego elementu tablicy
nitem – ilość elementów
stride – co który element
Do jednego bufora można pakować kilka tablic z danymi różnego typu.
38
Funkcje rozpakowujące
int info = pvm_unpackf( const char *fmt, ... )
int info = pvm_upkbyte( char *xp, int nitem, int stride)
int info = pvm_upkcplx( float *cp, int nitem, int stride)
int info = pvm_upkdcplx( double *zp, int nitem, int stride)
int info = pvm_upkdouble( double *dp, int nitem, int stride)
int info = pvm_upkfloat( float *fp, int nitem, int stride)
int info = pvm_upkint( int *ip, int nitem, int stride)
int info = pvm_upkuint( unsigned int *ip, int nitem, int stride )
int info = pvm_upkushort( unsigned short *ip, int nitem, int stride )
int info = pvm_upkulong( unsigned long *ip, int nitem, int stride )
int info = pvm_upklong( long *ip, int nitem, int stride)
int info = pvm_upkshort( short *jp, int nitem, int stride)
int info = pvm_upkstr( char *sp )
Pierwszy parametr to wskaźnik do pierwszego elementu tablicy
nitem – ilość elementów
stride – co który element
Rozpakowywanie musi odbywać się w tej samej kolejności co pakowane.
39
Wysyłanie wiadomości
int info = pvm_send( int tid, int msgtag ) wysyła wiadomość do odbiorcy.
Jeżeli błąd to zwraca <0.
tid – identyfikator odbiorcy
msgtag – etykietka komunikatu
int pvm_mcast(int *tids, int ntask, int msgtag) – rozgłoszenie komunikatu do wielu
odbiorców. Jeżeli błąd to zwraca <0.
tids – wskaźnik do tablicy tidów adresatów.
ntask – ilość tidów w tablicy
msgtag – etykietka komunikatu
int info = pvm_psend( int tid, int msgtag, char *buf, int len, int datatype )
robi wszystko w jednym. Czyli inicjacja bufora pakowanie i wysyłanie. Jeżeli błąd
to zwracane <0.
tid – gdzie mamy wysłać wiadomość
msgtag –etykietka komunikatu >=0.
datatype – typ danych PVM_BYTE, PVM_SHORT, PVM_INT, PVM_FLOAT,
PVM_CPLX, PVM_DOUBLE, PVM_DCPLX,
PVM_LONG_BYTE, PVM_SHORT, PVM_INT,
PVM_FLOAT, PVM_CPLX, PVM_DOUBLE,PVM_DCPLX,
PVM_LONG
40
Odbieranie wiadomości
int bufid = pvm_recv( int tid, int msgtag ) odbiór z czekaniem
tid – skąd mamy odebrać wiadomość
msgtag – jaką ma mieć etykietkę –1 wszystkie
#include <sys/time.h>
int bufid = pvm_trecv( int tid, int msgtag, struct timeval *tmout ) odbiór z timeoutem
tid – skąd mamy odebrać wiadomość
msgtag – jaką ma mieć etykietkę –1 wszystkie
timeout – ile czasu mamy na nią czekać
int bufid = pvm_nrecv( int tid, int msgtag ) – bez czekania tylko sprawdza i jak nic nie ma
to idzie dalej. Jeżeli brak wiadomości to zwraca 0.
tid – skąd mamy odebrać wiadomość
msgtag – jaką ma mieć etykietkę –1 wszystkie
int (*old)() = pvm_recvf(int (*new)(intbufid, int tid, int tag)) podmienienie funkcji odbioru
41
Inne informacje
int info = pvm_sendsig( int tid, int signum ) wysłanie sygnału do danego
procesu
int info = pvm_notify( int what, int msgtag, int cnt, int *tids )
funkcja ta testuje wystąpienie zdarzeń takich jak dodanie hosta
istnienie procesu, w rezultacie do procesu wywołującego tą funkcje
wysyłane są komunikaty (sygnały) informujące o zajściu powyższych
zdarzeń.
int ntids = pvm_siblings( int **tids ) - zwraca numer i id procesów, które
rozpoczęły się razem w pojedynczym wywołaniu. Ale tylko dla konsoli
bo przy wywołaniu przez pvm_spawn zwraca zawsze jeden i
identyfikator bieżącego procesu.
ntids – ilość tidów
tids – wskaźnik do tablicy gdzie ma umieścić identyfikatory bliźniaków
42
Zarządzanie procesami
int pvm_mytid(void) – zwraca identyfikator zadania (TID) w postaci dodatniej
liczby całkowitej. Jeżeli wartość jest ujemna to wtedy jest to błąd. Powoduje
rejestracje zadania w systemie PVM.
int pvm_exit(void) – służy do opuszczenia maszyny wirtualnej przez zadanie.
Zwrócić może np. info PvmSysErr.
int pvm_kill(int tid) – zatrzymuje dany proces. Wysyła mu SIGTERM. Jeżeli się
uda zwracane jest 0 jak nie to
liczba ujemna.
43
Zarządzanie procesami
int pvm_spawn(char *task, char **argv, int flag, char *where, int ntask, int *tids)
tworzy nowe procesy. Zwraca ilość stworzonych procesów lub numer błędu.
task – nazwa programu wykonywalnego, który musi być w katalogu
$PVM_PATH lub domyślnie w $HOME/pvm3/bin/$PVM_ARCH/
argv – wskażnik do tablicy argumentów przekazywanych do programu task
flag – opcje
PvmTaskDefault 0 – pvm wybiera sobie dowolną maszynę do
wystartowania nowego procesu
PvmTaskHost
1 – where określa na jakim hoście ma być
uruchomiony proces
PvmTaskArch
2 – where określa architekturę na jakiej uruchamiane
będą procesy
PvmTaskDebug 4 – uruchamia proces pod debuggerem
PvmTaskTrace
8 – uruchomienie procesu z włączonym systemem
traceingu
where – gdzie ma być uruchomiony proces. Może to być nazwa hosta
np. aom.bom.com albo nazwa architektury np. LINUX, SUN4,
ntask – liczba kopii jaka ma być uruchomiona
tids – Tablica o dlugości przynajmniej ntask , wypełniana jest identyfikatorami
nowych procesów
44
Dynamiczna konfiguracja
int pvm_addhost(char **hosts, int nhost, int *infos) – dodanie hosta
do maszyny wirtualnej.
hosts – wskaźnik do tablicy zawierającej nazwy hostów które
zostaną dodane do maszyny wirtualnej,
nhosts – liczba hostów do dodania
infos – wskaźnik do tablicy w której funkcja zapisze statusy
operacji włączenia hostów do maszyny.
int pvm_delhost(char **hosts, int nhost, int *infos) – usunięcie hosta
z maszyny wirtualnej.
hosts – wskaźnik do tablicy zawierającej nazwy hostów które
zostaną usunięte z maszyny wirtualnej,
nhosts – liczba hostów do usunięcia
infos – wskaźnik do tablicy w której funkcja zapisze statusy
operacji usunięcia hostów z maszyny
int pvm_halt(void) – zatrzymaj cały system pvm.
45
Dynamiczna konfiguracja
int info = pvm_start_pvmd( int argc, char **argv, int block )
start nowego demona pvm.
argc – ilość argumentów
argv – tablica argumentów
block - specyficzna liczba całkowita określająca czy
blokować. Jeżeli >0 to dopóki wszystkie hosty z
ewentualnego pliku hostfile nie zostaną dodane to funkcja
ta jest blokowana
46
Funkcje informacyjne
int pvm_mytid(void) – już wiemy
int pvm_parent(void) – zwraca identyfikator rodzica,
albo PvmNoParent jeśli nie został utworzony przez pvm_spawn.
int pvm_pstat(int tid) – zwraca status danego procesu.
PvmOk – jeżeli proces działa
PvmNoTask – jeżeli brak procesu
PvmBadParam – jeżeli zły parametr tid
tid – identyfikator procesu
int pvm_tidtohost(int tid) – zwraca identyfikator hosta (pvmd) na
którym dane zadanie uruchomiono
int pvm_perror(char *msg) – Zwraca informacje o błędzie.
Podajemy dodatkowy opis.
47
Funkcje informacyjne
int pvm_tasks(int which, int *ntask, struct pvmtaskinfo **taskp) –
udziela informacji o zadaniach wykonywanych przez maszynę
wirtualną.
which - jakiego rodzaju zadania, 0 wszystkie,
pvmd tid dla danego hosta tid podane zadanie
ntask – zwraca ilość zadań
taskp – wskaźnik do tablicy struktur danych zadań.
struct pvmtaskinfo{
int ti_tid; // identyfikator zadania
int ti_ptid; // identyfikator rodzica
int ti_host; // identyfikator hosta, pvmd
int ti_flag; // status zadania
char *ti_a_out; // nazwa wywoŒanego zadania,
wystartowane r•cznie zwracaj^ nic.
int ti_pid; // pid procesu
} taskp;
48
Funkcje informacyjne
int pvm_getopt(int what) – pokazuje różne opcje pvm liba.
what – co mamy pobrać
PvmRoute
1 routing
PvmDebugMas 2 debug mask
PvmAutoErr
3 auto error reporting
PvmOutputTid 4 standardowe wyjście dla dzieci
PvmOutputCode 5 output msgtag
PvmTraceTid
6 standardowe wyjście dla dzieci
PvmTraceCode 7 trace msgtag
PvmFragSize
8 message fragment size
PvmResvTids 9 Allow message to reserved tags and TIDs
zwracana wartość to:
PvmRoute
0
PvmDontRoute 1
PvmAllowDirect 2
PvmRouteDirect 3
49
Ustawianie opcji
int pvm_setopt(int what, int val) – ustawia odpowiednie opcje:
PvmRouteDirect – używa TCP by połączyć bezpośrednio procesy
PvmAllowDirect jest domyślny.
PvmDebugMask – dla tej opcji val jest poziomem debugowania.
PvmAutoErr: Domyślnie 1 włączone, 0 wyłączone 2 powoduje wyjście z
programu po wyświetleniu komunikatu błędu.
PvmOutputTidF: dla tej opcji val oznacza standardowe wyjście dla
dziecka.
PvmOutputCode: Wartość etykietki wiadomości używanej przy
otrzymywaniu wiadomości zawierających wyjście od innych zadań.
PvmFragSize: Określa ile bajtów ma zawierać wiadomość.
PvmResvTids: jeśli 1 to pozwala wysyłać wiadomości z
zarezerwowanymi etykietkami i do nie taskowych odbiorców.
Normalnie domyślnie jest 0 i zwraca błąd PvmBadParam.
50
Grupy
Group Server – dodatkowy demon działający pod
kontrolą PVM zarządzający grupami procesów
Uruchomienie $PVM_ROOT/lib/
$PVM_ARCH/pvmgs &
Kompilacja programu wykorzystującego
groupserver wygląda tak:
gcc –L/$PVM_ROOT/lib/$PVM_ARCH –I$PVM_ROOT/include
program.c –o program –lpvm3 -lpvmg3
51
Grupy
int inum = pvm_joingroup(char *group) – dołączenie się do grupy.
Zwracana wartość inum to identyfikator członka w grupie,
group – nazwa grupy
int pvm_lvgroup(char * group) – opuszczenie grupy. Jeżeli błąd to <0.
group – nazwa istniejącej grupy.
int inum = pvm_getinst(char *group, int tid) – zwraca inum
identyfikator procesu w grupie. Licząc od 0. Jeżeli <0 to znaczy błąd.
group – nazwa grupy
tid – identyfikator procesu
int pvm_gettid(char *group, int inum) – zwraca tid na podstawie
identyfikatora grupy. Jeżeli błąd to <0.
int pvm_getsize(char *group) – zwraca ilość członków grupy.
Jeżeli <0 to znaczy błąd
52
Grupy
int pvm_barrier(char *group, in count) – blokuje wywołujące procesy do czasu
gdy count członków grupy group nie wywoła pvm_barrier. Funkcja zwraca 0
jeżeli ok. jeżeli nie to <0.
group – nazwa grupy
count – Ilość członków by przekroczyć barierę. jeżeli –1 to wszyscy członkowie
grupy.
int pvm_bcast(char *group,int msgtag) – wysyłanie komunikatu do wszystkich
członków grupy. By wysłać taki komunikat nie trzeba być członkiem grupy.
Jeżeli ok. to 0 jak nie <0.
group – nazwa grupy
msgtag >= 0 – etykieta komunikatu.
53
Grupy
int pvm_reduce(void (*func)(),void *data, int count, int datatype, int msgtag,
char *group, int root) – wykonanie globalnej operacji.
func – definiuje operacje wykonywaną na globalnych danych.
Predefiniowane funkcje to:
PvmMin – minimum
PvmMax - maksimum
PvmSum – suma
PvmProduct – iloczyn
data – wskaźnik do początku lokalnych danych. Na wyjściu w procesie root
dane zostaną nadpisane przez wynik.
count – ilość elementów danych w tablicy data
datatype – typ danych. PVM_BYTE, PVM_SHORT, PVM_INT, PVM_FLOAT,
PVM_CPLX, PVM_DOUBLE, PVM_DCPLX, PVM_LONG
msgtag – etykietka komuniktu <= 0.
group – nazwa istniejącej grupy
root – identyfikator procesu w grupie który zbierze wyniki
54
Grupy
void func(int *datatype, void *, void *y, int * num, int *info) – funkcja
użytkownika do operacji redukcji.
datatype – typ danych na jakich będziemy operować
x – to samo co data powyżej, czyli jakby dane wejściowe
y – dane wyjściowe
num – ilość danych x, to samo co count powyżej
info – wyniki.
55
Grupy
int info = pvm_scatter( void *result, void *data, int count, int
datatype, int msgtag, char *group, int rootginst)
wykonuje rozproszenie danych z określonej grupy roota dla
każdego z elementów grupy w tym dla siebie
result – wskaźnik początkowy tablicy o długości count i typie danych
datatype który będzie nadpisany przez komunikat od roota grupy. (tu
trafi część danych)
data – wskaźnik do początku tablicy danych typu datatype skąd root
będzie rozsyłał dane do innych członków grupy. Jeżeli grupa liczy
n to data powinien mieć przynajmniej n*count Każdy z grupy w tym
także root dostanie po kawałku z tablicy data.
count – ilość elementów typu datatype które mają być wysłane do
członków grupy.
msgtag – etykietka
group – nazwa grupy
rootginst – identyfikator przywódcy grupy
56
Grupy
int info = pvm_gather( void *result, void *data, int count, int datatype,
int msgtag, char *group, int rootginst)
root grupy zbierze informacje od innych i umieści w result. Rozmiar
result w root musi być przynajmniej count*n (n- ilość członków w
grupie).
57
Skrzynki kontaktowe
int index = pvm_putinfo( char *name, int bufid, int flags ) – wkłada
informacje do skrzynki.
name – klucz bazy danych (nazwa klasy)
bufid – uchwyt bufora wiadomości
flags – flagi opcji
PvmMboxDefault – usuwana przez właściciela
PvmMboxPersistent – wiadomość pozostaje nawet jak
właściciel wyjdzie.
PvmMboxMultiInstance – trzymanie wiadomości o tych samych
nazwach.
PvmMboxOverWritable – pozwala na zapis oraz usuwanie przez
innych.
58
Skrzynki kontaktowe
int bufid = pvm_recvinfo( char *name, int index, int flags ) – działa
jak pvm_recv z tą różnicą że bierze dane z bazy o pasującym
kluczu name i index.
flags:
PvmMboxDefault – tylko dokładnie pasujące name i index bierz
pod uwagę.
PvmMboxFirstAvail – weź pierwszy rekord pasujący z name
gdzie index jest większy bądź równy do danego parametru.
PvmMboxReadAndDelete – przeczytaj i usuń.
int info = pvm_delinfo( char *name, int index, int flags ) – usuwa
wskazany rekord. Flagi nie są obecnie określone
59
Skrzynki kontaktowe
int info = pvm_getmboxinfo( char *pattern, int *nclasses, struct
pvmmboxinfo **classes) – podaje wskaźnik do listy
struktur pvmmboxinfo. Pamięć jest alokowana przez
libpvm i
realokowana przy następnym wywołaniu.
struct pvmmboxinfo {
char *mi_name;
int
mi_nentries;
int *mi_indices;
int *mi_owners;
int *mi_flags;
};
60
Skrzynki kontaktowe - przykład
/*wyslanie*/
sprintf( message, "Pozdrowienia od procesu A. );
pvm_initsend( PvmDataDefault );
pvm_pkint( &mytid, 1, 1 );
pvm_pkint( &context, 1, 1 );
pvm_pkstr( message );
if (( pvm_putinfo( “News1”, pvm_getsbuf(), PvmMboxDefault )) ==
PvmExists)
{
printf( "Nie można umieścić wiadomości, News1 już
istnieje”);
exit( -1 );
}
/*odebranie*/
if (( msg_buf = pvm_recvinfo(“News1”, 0, PvmMboxFirstAvail )) >= 0 )
{
pvm_setrbuf( msg_buf );
pvm_upkint( &their_tid, 1, 1 );
pvm_upkint( &their_context, 1, 1 );
pvm_upkstr( message );
61
}
Forwarding wiadomości
int info = pvm_pkmesg( int bufid ) – pakuje określoną wiadomość
do bieżącego bufora nadawczego.
Nagłówek2
Nagłówek1
Nadawca1,
odbiorca1,
rozmiar1...
Treść1:
123,
321L,
„bla bla bla”
Nadawca2,
odbiorca2,
rozmiar2...
Nagłówek1
Nadawca1,
odbiorca1,
rozmiar1...
Treść:
123,
321L,
„bla bla bla”
„i coś jeszcze”
62
Forwarding wiadomości
int newbufid = pvm_upkmesg( ) – rozpakowanie odebranej
wiadomości. Nagłówek wiadomości zostaje jak w oryginale.
int info = pvm_pkmesgbody( int bufid ) – pakuje tylko same
dane z wiadomości. Typ pakowania musi się zgadzać
Nagłówek1
Nagłówek2
Nadawca1,
odbiorca1,
rozmiar1...
Nadawca2,
odbiorca2,
rozmiar2...
Treść1:
123,
321L,
„bla bla bla”
Treść:
123,
321L,
„bla bla bla”
63
Forwarding wiadomości
pvm_recv(-1, -1);
pvm_initsend(PvmDataDefault);
pvm_pkstr("To jest wiadomość którą odebrałem...");
pvm_pkmesg(pvm_getrbuf());
64
Inne mniej lub bardziej ciekawe
Funkcje do tworzenia kontekstów:
int ctx = pvm_newcontext( void )
int old_ctx = pvm_setcontext( int new_ctx )
int info = pvm_freecontext( ctx )
int ctx = pvm_getcontext( void )
65
Inne mniej lub bardziej ciekawe
int info = pvm_hostsync( int host, struct timeval *clk, struct timeval
*delta ) – pobierz czas z hosta pvm.
host – tid hosta
clk – czas zdalnego hosta
delta – różnica czasu
int info = pvm_gettmask( int who, Pvmtmask mask ) - ślady maski, są one
dziedziczone, służą do debugowania
int info = pvm_settmask( int who, Pvmtmask mask )
pvm_reg_hoster() - rejestrowanie procesu jako hostera czyli takiego co to
startuje inne demony.
int cc = pvm_reg_rm( struct pvmhostinfo **hip ) - Rejestrowanie
wywoływanego zadania jak zadania jako menadżera zasobów.
int cc = pvm_reg_tasker() – Rejestrowanie wołającego zadania jako starter
procesów.
66

Podobne dokumenty