1 / 15 Vorlesung Betriebssysteme II Thema 3: IPC Robert Baumgartl 20. April 2015
2 / 15 Message Passing (Nachrichtenaustausch) Prinzip 2 grundlegende Operationen: send(), receive() notwendig, wenn kein gemeinsamer Speicher (verteilte Systeme) auch mit gemeinsamem Speicher möglich (z.b. Mikrokerne) erforderliche Funktionalität: Synchronisierung (synchron/asynchron, d.h., blockierend / nichtblockierend) Adressierung des Kommunikationspartners Authentifizierung
Synchronisation mit Nachrichten 3 / 15 a) beide blockieren ( Rendezvous ) keine Pufferung notwendig, Kopieraufwand z.b. Server-Client-Interaktion implizite Empfangsbestätigung b) receive() blockiert, send() blockiert nicht ( No-Wait-Send ) explizite Empfangsbestätigung nötig c) beide blockieren nicht Modifikation: Blockierung mit Timeout statt vollständiger Blockierung
4 / 15 Adressierung direkt: Empfängerprozeß benannt indirekt: Nachricht an Datenstruktur gesendet, Empfänger holt Nachricht von DS ab (flexibler) Port Mail box Abbildung: Message Passing mit Port (m:1), z.b. Mach Abbildung: Message Passing mittels Mailbox (m:n)
5 / 15 Praxisbeispiele für Message Passing MPI - Message Passing Interface standardisierte Bibliothek zur Programmierung von Parallelrechnern und heterogenen Netzen Senden sowohl synchron als auch gepuffert, Empfang stets synchron > 150 Rufe
Einfaches MPI-Beispiel (2 Knoten, FORTRAN) 6 / 15 include mpif.h integer myrank, numprocs, ierr integer status(mpi_status_size) real side, square side = 7.0 square=0.0 C call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, myrank, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, numprocs, ierr ) print *, I am node,myrank, out of,numprocs, nodes. if(myrank.eq.1) then square = side * side call MPI_SSEND(square,1,MPI_REAL,0,99,MPI_COMM_WORLD,ierr) endif if(myrank.eq.0) then print *, Before receive square is,square call MPI_RECV(square,1,MPI_REAL,1,99,MPI_COMM_WORLD,status,ierr) print *, After receive square is,square endif call MPI_FINALIZE(ierr) end
Anmerkungen 7 / 15 call MPI_SEND(square,1,MPI_REAL,0,99,MPI_COMM_WORLD,ierr) Sendepuffer Datentyp Ziel prozeß Communicator Fehlerzustand Anzahl zu sendender Einträge Tag Abbildung: Parameterbedeutung bei MPI_SEND Daten werden mittels sog. Communicators ausgetauscht; MPI_COMM_WORLD schliesst alle Knoten ein. MPI_COMM_RANK ermittelt für jeden Knoten den ID Tag (99) dient der Selektion von Kommunikationspartnern MPI_SSEND ist synchron, MPI_BSEND buffered; MPI_RECEIVE immer synchron
8 / 15 Praxisbeispiele für Message Passing Mikrokern L4 synchrone, ungepufferte IPC mit Timeouts für send() und receive(): 0 asynchrone IPC, blockierend, sonst µs-granularität http://os.inf.tu-dresden.de/l4/
9 / 15 Praxisbeispiele für Message Passing Pascal-FC Kanäle (channel of <type>) zur Kommunikation synchrone Operationen Send: <Kanal>! <Variable> Receive: <Kanal>? <Variable> vgl. Communicating Sequential Processes CSP (Hoare)
Erzeuger-Verbraucher-Problem mit Message Passing Pascal-FC program erzvermp ; var l i n k : channel of char ; process producer ; var l o c a l : char ; begin f o r l o c a l := a to z do begin ( produce item ) l i n k! l o c a l ; end end ; ( producer ) process consumer ; var l o c a l : char ; begin repeat begin l i n k? l o c a l ; ( consume item ) w r i t e l n ( read:, l o c a l ) ; end u n t i l l o c a l = z ; end ; ( consumer ) begin cobegin producer ; consumer coend end. 10 / 15
11 / 15 Praxisbeispiele für Message Passing Nachrichtenwarteschlangen in der System-V-IPC Syscall msgget msgctl msgrcv msgsnd Semantik Anlegen (und Zugriff) einer MQ Manipulation einer MQ Empfang einer Nachricht Senden einer Nachricht Wiederum gibt es eine zweite API: POSIX Message Queues (vgl. man mq_overview) Praktikum einfaches Beispiel: msgclient.c, msgserver.c, share.h (extern)
12 / 15 Shared Memory Idee: Mehr als einem Prozess Zugriff auf ein (wohldefiniertes) Stück Speicher gewähren. weicht das Prozess-Konzept ein wenig auf sehr effizient, da keine Daten transportiert werden müssen keine implizite Synchronisation (wie bei Sockets, Pipes oder Message Passing) Zugriff muss durch Prozesse selbst koordiniert werden (Semaphore, Bedingungsvariable, Monitore,......) Threads innerhalb ein- und desselben Prozesses nutzen per definitionem keinen Shared Memory
Systemrufe in der System-V-API 13 / 15 1. Anlegen des Segmentes mittels shmget() genau ein Prozess muss das Segment kreieren alle weiteren Prozesse müssen sich damit Zugriff verschaffen Größe (size) wird auf ein Vielfaches der Seitengröße aufgerundet Resultat: Identifikator des Segmentes 2. Einblenden des Segmentes mittels shmat() (attach) Einblende-Adresse wählbar oder durch das System vorgegeben Resultat: Zeiger auf den Beginn des Segmentes 3. Zugriff auf das Segment (über Zeigervariable; keine Systemrufe nötig)
Systemrufe in der System-V-API... continued 14 / 15 4. Ausblenden des Segmentes mittels shmdt() (detach) 5. Manipulation des Segmentes mittels shmctl() (control) wiederum unterschiedliche Kommandos für verschiedene Management-Aufgaben IPC_RMID - zum Zerstören markieren (Zerstörung erst nach letztem Detach) IPC_INFO - Abrufen systemweiter Limits bezüglich Shared-Memory-Segmente (Größe, Anzahl) SHM_LOCK - Verhinderung des Paging (Linux-spezifisch)
15 / 15 POSIX-API für Shared Memory wiederum gibt es eine zur System-V-IPC alternative API sehr eng an Syscalls für Dateien (open(), unlink()) angelehnt Ruf shm_open() shm_unlink() mmap() munmap() Semantik Anlegen/Öffnen eines Segmentes Löschen eines Segmentes Einblenden des Segmentes Ausblenden des Segmentes