Jonny Karlsson PROCESSPROGRAMMERING Föreläsning 4 ( ) Innehåll: -Programmerade rörledningar -Namngivna rörledningar
Jonny Karlsson Programmerade rörledningar Är det äldsta och fortfarande vanligaste sättet att förverkliga kommunication mellan UNIX-processer Används vanligen för kommunikation mellan en föräldraprocess och en eller flera barnprocesser Begränsningar: Kan endast användas mellan processer som är släkt med varandra i rakt nedstigande led. (minst en fork i mellan) Kommunikationen är Halv-Duplex (kommunikation möjlig endast i en riktning
Jonny Karlsson Programmerade rörledningar ATT SKAPA EN PROGRAMMERAD RÖRLEDNING En programmerad rörledning skapas i ett C-program med systemanropet pipe int pipe(int filedes[2]); pipe skapar, förutom själva rörledningen, ett par fildeskriptorer filedes[0]Pekar på rörledningens läsända filedes[1]Pekar på rörledningens skrivända Returnerar:0 vid framgång -1 vid misslyckande
Jonny Karlsson Programmerade rörledningar ATT SKRIVA TILL ELLER LÄSA FRÅN EN RÖRLEDNING Skrivning till eller läsning från en programmerad rörledning kan göras på samma sätt som vid filhantering Man skriver till rörledningens skrivända: write(filedes[1], buffer, strlen(buffer)); och läser från rörledningens läsända: read(filedes[0], buffer, strlen(buffer)); En fildeskriptor kan associeras med en strömpekare med systemanropet fdopen strompek = fdopen(filedes[1], ”w”); strompek2 = fdopen(filedes[0], ”r”); Vartefter man kan skriva till rörledningen med fprintf(strompek,...) och läsa ur rörledningen med fscanf(strompek2,...)
Jonny Karlsson Programmerade rörledningar STÄNGNING AV EN ÖPPEN RÖRLEDNING Görs på samm sätt som vid stängning av en öppen filer: close(filedes[0]);Stänger rörledningens läsända close(filedes[1]);Stänger rörledningens skrivända
Jonny Karlsson Programmerade rörledningar ANVÄNDNING AV PROGRAMMERADE RÖRLEDNINGAR Om kommunikation i båda riktningarna mellan två processer önskas, krävs två rörledningar Vanligen skapar föräldraprocessen först 2 rörledningar och kallar därefter på fork. Därefter stänger föräldra- och barnprocessen var sin ända av var sin rörledning. Exempel1
Jonny Karlsson Programmerade rörledningar För en process som uppstartats av barnprocessen till följd av kodbyte (execl) är deskriptortabellen (filedes[2]) som skapats i förldraprocessen obekant. Man brukar därför koppla rörledningens läsända till standard input och skrivända till standard output i barnprocessen. Detta måste göras i barnprocessen före kodbyte. En rörlednings läsanda kopplas till standard input enligt följande: close(0)Standard input stängs dup(filedes[0])Skapar en kopia av rörledningens läsdeskriptor med lägsta möjliga deskriptorvärde (I detta fall 0 eftersom deskriptor 0 stängdes före dup close(filedes[0])Ursprungliga läsdeskriptorn stängs Efter detta kan barnprogrammet som uppstartats som följd av kodbyte läsa data ur rörledningen via deskriptor 0 eller strömpekare stdin En rörlednings skrivända kopplas till standard output på motsvarande sätt. Exempel 2.
Jonny Karlsson Namngivna rörledningar Kallas även FIFO:s Kan användas som kommunkationskanal mellan två processer även om dessa inte är ”släkt” med varandra. En FIFO är i själva verket en typ av fil med speciella egenskaper. Dessa syns i katalogträdet som filer men skiljer sej från vanliga filer genom att de har symbolen p framför skyddskoden. En fil kan ej vara öppen och hanteras av många processer samtidigt men det kan däremot en FIFO. Används huvudsakligen för två ändamål i UNIX: för att via rörledningstecken på kommandoraden (|) skicka utdata från en process som indata till en annan process. På så vis behövs inga temporära filer för att skicka data mellan en klient och en server i Klient-Server miljöer
Jonny Karlsson Namngivna rörledningar ATT SKAPA EN NAMNGIVEN RÖRLEDNING Skapas från kommandoraden med UNIX kommandot mknod mknod pipename pSkapar en namngiven rörledning med namnet ”pipename” i innevarnade katalog Skapas i ett C-programm med systemanropet mknod() eller mkfifo() mknod(char *pipename, int mode, int dev); pipenamepekar på objektets (rörledningens) filnamn modedefinierar skyddskoden 0010ugo devsaknar betydelse (=0) Ex. mknod(”rorledning”, , 0)
Jonny Karlsson Namngivna rörledningar HANTERING AV NAMNGIVNA RÖRLEDNINGAR En namngiven rörledning kan öppnas med open() eller fopen(), precis som en fil. int open(char *objektnamn, int mode) objektnamnpekare på en teckentabell som innehåller filnamnet på rörledningen mode0 – öppna för läsning 1 – öppna för skrivning 2 – öppna för både läsning och skrivning FILE *fopen(const char *objektnamn, const char *mode) moder – öppna för läsning w – öppna för skrivning
Jonny Karlsson Namngivna rörledningar Vid användning av open() kan man med flaggan O_NONBLOCK bestämma vad som händer: Om O_NONBLOCK inte anges som parameter till open() kommer öppning för endast läsning att blockera processen tills någon anna proces öppnar samma FIFO för skrivning. Likväl kommer en öppnig för endast skrivning att blockera processen till någon anna process öppnar samma FIFO för läsning Om flaggan O_NONBLOCK anges som parameter till open() så kommer en öppning för endast läsning att returnera direkt och processen kan fortsätta exekveringen. Om FIFO:n öppnas för skrivning och ingen annan process har öppnat samma FIFO förläsning, kommer felet ENXIO att returneras. Exempel 3: