Die Verwaltung aller Tasks unter
PVM
erfolgt über Dämon-Prozesse, die auf
jedem Rechner existieren, der an der virtuellen Maschine beteiligt ist.
Die Dämonen übernehmen die Nachrichtenverwaltung, die Verteilung der
Tasks auf die einzelnen Rechner der virtuellen Maschine und die
Ein-/Ausgabe der einzelnen Tasks.
Der zuerst gestartete Dämon ist der Master-Dämon, der einige
zusätzliche Aufgaben erfüllt, wie zum
Beispiel das Rekonfigurieren der virtuellen Maschine durch das Starten
bzw. Eliminieren anderer
Dämon-Prozesse, was zur Laufzeit einer Applikation erfolgen
kann.
Das Starten einzelner Tasks kann entweder aus einem speziellen
Kommandoprozessor, der
PVM -Console,
heraus oder durch andere Tasks erfolgen.
Dabei kann in dem entsprechenden Funktionsaufruf ( pvm_spawn())
ein Rechner, der an der virtuellen Maschine beteiligt ist,
oder eine bestimmte Architektur
in einem heterogenen Netz angegeben werden, auf der die Task innerhalb
der virtuellen Maschine gestartet werden soll.
Ohne diese Angaben
werden die Tasks gleichmäßig auf die Hosts verteilt,
wobei man deren relative Rechenleistung bei der Konfigurierung der
virtuellen Maschine angeben kann.
Die Identifikation der einzelnen Tasks auf der virtuellen Maschine
erfolgt über Task IDs.
Diejenige Task, welche mittels pvm_spawn()
weitere Tasks gestartet hat, erhält deren
TID .
Jede Task kann ihre eigene
TID
( pvm_mytid()) und die ihrer Vater-Tasks ( pvm_parent())
erfragen und durch diese die
TIDs
der anderen Tasks auf der virtuellen Maschine erfahren.
Der folgende Code zeigt die Initialisierung eines
Masters im Master-Slave Prozeßmodell.
#include "pvm.h" #define NUM 4 #define WORK 0 #define RES 42 void main (void) { int info, i, slaves[NUM], work[NUM], res[NUM], total; info = pvm_spawn("slave", (char **) 0, PvmTaskArch, "SUN4", NUM, slaves); if (info != NUM) { printf("%d tasks started", info); pvm_exit(); exit(-1); } work = DivideWork(NUM); /* Arbeit austeilen */ for (i=0; i < NUM; i++) { pvm_initsend (PvmDataDefault); pvm_pkint(&work[i], 1, 1); pvm_send(slaves[i], WORK); } /* Resultat aufsammeln */ for (i=0; i < NUM; i++) { pvm_recv(slaves[i], RES); pvm_upkint(&res[i], 1, 1); } total = ComposeResult(res); pvm_exit(); }
Die Master-Task startet, nachdem sie ihre eigene
TID
erfragt hat, vier Kopien des Programms
slave auf Hosts der Architektur SUN innerhalb der
virtuellen Maschine.
In dem Vektor slaves erhält der Master die
TIDs
der gestarteten Tasks.
Im folgenden werden einzelne Arbeitspakete an alle Tasks verschickt und
danach die errechneten Teilergebnisse empfangen und zusammengefaßt.
Das Hauptprogramm eines Slaves kann so aussehen:
void main (void) { int master, work_part, res; master = pvm_parent(); pvm_recv(master, WORK); pvm_upkint(&work_part, 1, 1); res = DoWork(work_part); pvm_initsend(PvmDataDefault); pvm_pkint(&res, 1, 1); pvm_send(master, RES); pvm_exit(); }