Dagens tema: Synkronisering

Like dokumenter
Dagens tema: Synkronisering

IN 147 Program og maskinvare. Dagens tema:

IN 147 Program og maskinvare

Oppsummering av IN147 siste del Operativsystemer Parallellisering Veien videre

Dagens tema: Parallellstyring

Kort notat om parallellstyring IN147

IN 147 Program og maskinvare. Vranglås De spisende filosofer Lettvektsprosesser Moderne synkroniseringsmetoder Meldinger Monitorer Linda

IN 147 Program og maskinvare

Løsningsforslag til eksamen i IN 147 og IN 147A

Dagens tema: Parallellisering Generelt Fraktaler Generelt Julia-kurven Vindussystemet X Parallellitet i UNIX Signaler. IN 147 Program og maskinvare

GetMutex(lock) { while(testandset(lock)) {} } En context switch kan ikke ødelegge siden testen og endringen av lock skjer i samme instruksjon.

Dagens tema: Liten repetisjon Håndtering av statusverdier

Løsningsforslag til eksamen i IN 147(A)

Dagens program. Operativsystemer Prosesser og systemkall i UNIX Hente prosessens nummer Starte prosesser Vente på prosesser Utføre programmer

EKSAMEN. Operativsystemer. 1. Læreboken "A Practical Guide to Red Hat Linux" av Mark Sobell 2. Maks. tre A-4 ark med selvskrevne notater.

Mer om C programmering og cuncurrency

IN 147 Program og maskinvare

Oversikt over IN147(A):

IN 147 Program og maskinvare

HØGSKOLEN I SØR-TRØNDELAG

IN 147 Program og maskinvare

Deadlocks og mer om concurrencymekanismer

Dagens tema. Nyttige programmer Programmet make. Flyt-tall Representasjon av flyt-tall. Standarden IEEE 754. Systemkall i Unix

En prosess kan sees på som et stykke arbeid som skal utføres på datamaskinen. Ofte vil det være flere prosesser/tråder på datamaskinen samtidig.

INF1010 Tråder II 6. april 2016

Programmering i C++ Løsningsforslag Eksamen høsten 2005

INF2810: Funksjonell Programmering. Muterbare data

Del 4 Noen spesielle C-elementer

Oppgave 1 Oversettelse (vekt 16%)

Concurrency. Lars Vidar Magnusson. September 20, Lars Vidar Magnusson () Forelesning i Operativsystemer September 20, / 17

Dagens tema INF1070. Signaturer. Typekonvertering. Pekere og vektorer. struct-er. Definisjon av nye typenavn. Lister

Dagens tema INF1070. Info om C. Cs preprosessor. Feilsøking. Dag Langmyhr,Ifi,UiO: Forelesning 31. januar 2005 Ark 1 av 29

Informasjon om C. Dagens tema INF1070 INF1070 INF1070 INF1070. Den viktigste kilden til informasjon om C (utenom en god. C-funksjonene.

Ny/utsatt EKSAMEN. Dato: 6. januar 2017 Eksamenstid: 09:00 13:00

Forslag til løsning på oppgavesett for uke 40

Løsningsforslag til eksamen i IN 147(A)

Programmeringsspråket C

Løsningsforslag til eksamen i IN147(A)

HØGSKOLEN I SØR-TRØNDELAG

IN1010 våren Repetisjon av tråder. 15. mai 2018

Oving 2. Oppgave 1. #include <stdio.h> int main(int argc, char **argv) { char *navn = argv[1]; printf ("Navnet ditt er %s\n", navn); } Oppgave 2

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet

Eksempler på ikke-blokkerende systemkall:

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet

Signaturer. Dagens tema. En vanlig feil int-funksjon. Dette kan noen ganger gi rare feilmeldinger: INF1070 INF1070 INF1070 INF1070

HØGSKOLEN I SØR-TRØNDELAG

Dagens tema. Nyttige programmer Programmet make. Hvis én fil endres, hvilke filer må da kompileres på nytt?

Oppgave 1 JK-flip-flop (Total vekt 20%)

Kapittel 1 En oversikt over C-språket

Tråder og concurrency i Linux

Del 1 En oversikt over C-programmering

Oppgavene 1, 2, 4, 5, 6, 9, 12 og 13 passer best til å løses ved en datamaskin.

alternativer til felles hukommelse store parallelle datamaskiner Tema for denne forelesningen: in 147, våren 1999 parallelle datamaskiner 1 9

Oppgave 1. Oppgave 2. Høgskolen i Østfold Avdeling for informasjonsteknologi

EKSAMEN. Emne: Algoritmer og datastrukturer

Dagens tema INF2270. Cs preprosessor. Separat kompilering av C funksjoner. C og minnet. Dag Langmyhr,Ifi,UiO: Forelesning 5. februar 2007 Ark 1 av 15

Dagens tema: Datastrukturer

Oppgave 1 - Linux kommandolinje (%)

IN 147 Program og maskinvare

INF3140 Modeller for parallellitet INF3140/4140: Låser og Barrierer

Pekere og vektorer. Dagens tema. I C gjelder en litt uventet konvensjon:

Dagens tema. Det siste om C Pekere og vektorer. Pekere til pekere. Vanlige pekerfeil. struct-er og typedef. Lister. Feilsøking

Plan. Oppgaver og repetisjon Eksempler med fikspunkt og induksjon: 1. sortering 2. divisjon 3. Heis? IN 315: Foilsett 9: Unity: Arkitekturer

Ark 1 av 18. programmeringsspråkenes. Velkommen til IN 211. verden. IN 211 Programmeringsspråk

Eksamen DAT 103. Oppgave 2. Kandidatnr.: 145 1) B 2) B 3) A 4) A 5) D 6) C 7) B 8) A 9) A 10) D

IN Algoritmer og datastrukturer

INF2810: Funksjonell Programmering. Strømmer

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Strømmer

Løsnings forslag i java In115, Våren 1996

EKSAMENSOPPGAVE. INF-1100 Innføring i programmering og datamaskiners virkemåte. Ingen. Elektronisk (WiseFlow) Robert Pettersen

Hva er en kø? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn først

UNIVERSITETET I OSLO

Dagens tema. Adresser som parametre Dynamisk allokering Signaturer Definisjon av nye typenavn Typekonvertering Pekere og vektorer

Programmeringsspråket C Del 3

Hva er en kø? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn først

Programmeringsspråket C Del 3

Grunnleggende Datastrukturer

Nybegynnerkurs i C. Øyvind Grønnesby. 14. oktober Introduksjon Typer Operatorer Kontrollstrukturer Pekere Makroer Lenker

Dagens tema. Cs preprosessor Separat kompilering av C-funksjoner C og minnet Oversikt over operatorene

Faglig kontakt under eksamen: Orestis Gkorgkas

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

Løkker og arrayer. Løse problemer med programmering. INF1000, uke3 Geir Kjetil Sandve

E K S A M E N. Algoritmiske metoder I. EKSAMENSDATO: 11. desember HINDA / 00HINDB / 00HINEA ( 2DA / 2DB / 2EA ) TID:

INF1010 LISTER. Listeelementer og listeoperasjoner. Foran. Bak

IN 147 Program og maskinvare

IN 147 Program og maskinvare

IN 147 Program og maskinvare

KONTINUASJONSEKSAMEN

Norsk informatikkolympiade runde

Cs preprosessor. Dagens tema. Betinget kompilering

IN 147 Program og maskinvare

Informasjon Eksamen i IN1000 høsten 2017

Hvorfor sortering og søking? Søking og sortering. Binære søketrær. Ordnet innsetting forbereder for mer effektiv søking og sortering INF1010 INF1010

Programmeringsspråket C Del 3. Hans Petter Taugbøl Kragset

E K S A M E N. EKSAMENSDATO: 15. desember 1994 TID: Kladd og oppgavearkene leveres sammen med besvarelsen. Kladd merkes med "KLADD".

Dagens tema: Enda mer MIPS maskinkode

Tre på rad mot datamaskinen. Steg 1: Vi fortsetter fra forrige gang. Sjekkliste. Introduksjon

Backtracking som løsningsmetode

Transkript:

Dagens tema: Synkronisering Kappløp og kritiske regioner Blokkering Produsent/konsument-problemet Semaforer Fraktaleksemplet med semaforer og delt lager. «De spisende filosofer»: 3 gale løsninger En foreløbig oversikt Ark 1 av 29 Forelesning 12.4.2000

Kappløp Ved parallellprogrammering kan det oppstå en situasjon med kappløp («race condition»). Dette innebærer at resultatet av en kjøring avhenger av hvilken rekkefølge prosessene kjøres i og hvor fort de går i forhold til hverandre. Slike kappløp ønsker vi vanligvis ikke. Et typisk eksempel på kappløp er forrige ukes forsøk på å bruke felles lager til fraktalprogrammet: Ved å benytte synkronisering kan vi unngå kappløp. Forelesning 12.4.2000 Ark 2 av 29

Teknikker brukt hittil Teknikk Synk Data Spesielt UNIX filer UNIX rør Forutsetter samme urprosess. Kan ikke alltid brukes. Delt lager Forelesning 12.4.2000 Ark 3 av 29

Kritiske regioner Vanligvis kan flere prosesser kjøre uavhengig av hverandre lenge av gangen, men noen ganger kan de «tråkke hverandre på tærne» fordi de samtidig aksesserer en felles ressurs (vanligvis et delt lager). De delene av programmene hvor dette kan skje, kalles kritiske regioner. Når man skriver parallelle programmerer, er det viktig å finne de kritiske regionene og foreta seg noe spesielt der. I fraktalprogrammet var bruk av det felles lageret en kritisk region. Forelesning 12.4.2000 Ark 4 av 29

Beskyttelse av kritiske regioner Forskning har påpekt at for å skrive gode parallelle programmer som unngår kappløp, må koden oppfylle følgende fire krav: 1. Det må aldri være mer enn én prosess av gangen inne i hver kritiske region. 2. Prosessene må ikke forutsette noe om hverandres eksekveringshastighet. 3. En prosess utenfor kritisk region må ikke hindre en annen prosess å gå inn der. 4. Ingen prosess må vente uendelig lenge før den kan komme inn i kritisk region. (Dette kalles utsulting («starvation»).) Dette skal vi se på ulike teknikker for å oppnå. Forelesning 12.4.2000 Ark 5 av 29

Venting Noen teknikker er basert på venting, for eksempel int lock = 0;. while (lock) ; lock = 1; kritisk region lock = 0; Dette har to ulemper: Aktiv venting kaster bort mye tid. Flere prosesser kan stjele låsen samtidig. Venting bør kun brukes til å implementere bedre tekniker. Forelesning 12.4.2000 Ark 6 av 29

Blokkering Alle gode løsninger for synkronisering er basert på å la operativsystemet blokkere prosesser som ikke skal kjøre. Prosesser kan være i følgende tilstander: ' Blokkert & 1 '? ' & $ % Aktiv & Følgende overganger finnes: 6 4 3 - $ % ' & $ 2 $? Klar $ % 1. En prosess blokkeres (f eks fordi den venter på data). 2. Fordeleren velger en annen prosess. 3. Fordeleren velger denne prosessen til å kjøre. 4. En blokkert prosess får det den venter på. Forelesning 12.4.2000 Ark 7 av 29

Produsent/konsument-problemet Dette problemet er et av de aller mest kjente problemene innen parallellstyring. '$ &% P - Buffer - '$ &% K I dette systemet er det to prosesser: P produserer ett eller annet. Dette legges i bufferen. K konsumerer det P lager, dvs. henter det fra bufferen og gjør ett eller annet med det. Siden bufferen er begrenset, hender det at P eller K må ta en pause: P må stoppe hvis det ikke er mer ledig plass i bufferen. K må stoppe hvis det ikke er flere elementer å hente i bufferen. Dessuten må ikke mer enn én prosess av gangen aksessere bufferen. Forelesning 12.4.2000 Ark 8 av 29

Semaforer Semaforer ble oppfunnet i 1965 av Edsger Dijkstra og var den første praktisk brukbare mekanismen for parallellstyring. En semafor er en datastruktur: Verdi Kø - - - Semaforer har to operasjoner: down(&s) Hvis verdien til s er > 0, vil den bli senket med 1. Hvis ikke, vil prosessen bli blokkert og dens nummer lagt til køen til s. up(&s) Hvis køen til s er tom, økes verdien med 1. Hvis ikke, fjernes ett prosessnummer fra køen, og den tilhørende prosessen startes opp igjen. Forelesning 12.4.2000 Ark 9 av 29

Semaforer beskytter kritisk region semaphore mutex = 1; /* Mutual exclusion */. down(&mutex); Kritisk region up(&mutex); Med en slik beskyttelse er det garantert at maksimalt én prosess av gangen er i kritisk region. En semafor som kun har verdiene 0 og 1, kalles en binær-semafor. Forelesning 12.4.2000 Ark 10 av 29

Bruk av semaforer Hva skjer når en prosess vil inn i kritisk region? Hvis mutex.verdi> 0, er det bare å gå inn. Hvis mutex.verdi= 0, må prosessen vente. Ved å sette en annen initialverdi, kan man tillate flere inne i kritisk region samtidig. Forelesning 12.4.2000 Ark 11 av 29

PK-problemet løst med semaforer #define N 100 semaphore mutex = 1; semaphore empty = N; /* Teller tomme */ semaphore full = 0; /* Teller fulle */ producer() { int item; while (TRUE) { produce_item(&item); down(&empty); down(&mutex); enter_item(item); up(&mutex); up(&full); consumer() { int item; while (TRUE) { down(&full); down(&mutex); remove_item(&item); up(&mutex); up(&empty); consume_item(item); Forelesning 12.4.2000 Ark 12 av 29

Her skjer følgende: Det å sette verdier inn i bufferen (ved å kalle på funksjonen enter item) og ta dem ut derfra (ved å kalle remove item) er kritiske regioner. Disse beskyttes av en binær-semafor (mutex). For å blokkere producer når bufferen er full, innføres semaforen empty, som teller hvor lange tomme plasser det er i bufferen. Hvis det ikke er noen ledige plasser, vil producer bli blokkert. Når consumer harhentetetnyttelement fra bufferen, vil den øke empty. Hvis producer da var blokkert, vil den bli frigjort. For å blokkere consumer når bufferen er tom, innføres semaforen full, som teller hvor mange fulle posisjoner det er i bufferen. Hvis det ikke er noen fulle posisjoner, vil consumer bli blokkert. Når producer har lagt et nytt element i bufferen, vil den øke full. Hvis consumer da var blokkert, vil den bli frigjort. Forelesning 12.4.2000 Ark 13 av 29

Semaforer i SVIPC i UNIX For å kunne operere på semaforer i UNIX trenger vi et par definisjonsfiler: #include <sys/ipc.h> #include <sys/sem.h> En gruppe på n semaforer allokeres slik i SVIPC: int sem_id; sem_id = semget(ipc_private, /* Nøkkel */ n, /* Antall */ 0700); /* Aksesskode */ if (sem_id<0) perror("semprog"); Etter bruk må man huske å frigjøre semaforene: semctl(sem_id, 0, IPC_RMID); Forelesning 12.4.2000 Ark 14 av 29

Operasjonene down og up kan programmeres slik (uten at man trenger å forstå det): void down(int n) { struct sembuf op; int status; op.sem_num = n; op.sem_op = -1; op.sem_flg = 0; status = semop(sem_id, &op, 1); if (status!= 0) {{ printf("semaphore down error %d.\n", status); exit(1); void up(int n) { struct sembuf op; int status; op.sem_num = n; op.sem_op = 1; op.sem_flg = 0; status = semop(sem_id, &op, 1); if (status!= 0) {{ printf("semaphore up error %d.\n", status); exit(1); Forelesning 12.4.2000 Ark 15 av 29

Fraktal-eksemplet med semaforer Fraktal-eksemplet vårt er et meget godt eksempel på produsent-konsument-problemet: Én eller flere produsenter produserer kolonner med fraktalpunkter. Bufferen har plass til ett sett data. En konsument mottar kolonnene med data og tegner dem på skjermen. Dataoverføringen skjer via delt lager. Forelesning 12.4.2000 Ark 16 av 29

Deklarasjoner #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include "fraktal.h" #include "x147.h" extern pid_t safefork(void); #define NX 750 #define NY 550 #define MAX 180 #define MUTEX 0 /* Våre tre semaforer */ #define FULL 1 #define EMPTY 2 float x1 = -0.01, x2 = 0.01, y1 = -0.01, y2 = 0.01; typedef struct { int xpos; unsigned char ycol[ny]; col_data; int sh_mem_id, sem_id; col_data *sh_mem; Forelesning 12.4.2000 Ark 17 av 29

Hovedprogrammet Hovedprogrammet allokerer ressurer og starter produsentene og konsumenten. int main(int argc, char *argv[]) { time_t start_tid = time(null); int n_proc, nc; n_proc= argc <= 1? 1 : atoi(argv[1]); sh_mem_id = shmget(ipc_private,sizeof(col_data),0700); if (sh_mem_id < 0) perror("fraksem1"); sh_mem = shmat(sh_mem_id,0,0); sem_id = semget(ipc_private, 3, 0700); if (sem_id < 0) perror("fraksem1"); up(mutex); up(empty); /* Sett initialverdi. */ x147open(nx, NY); for (nc = 1; nc <= n_proc; ++nc) { if(safefork()==0){ produsent(nx*(nc-1)/n_proc, NX*nc/n_proc-1); exit(0); konsument(); printf("det hele tok %d sekunder.\n", time(null)-start_tid); x147pause(); terminate(0); Forelesning 12.4.2000 Ark 18 av 29

Produsentene Hver produsent skal generere data for sitt område av bildet. Når én kolonne er ferdig, sendes den til konsumenten. void produsent(int xstart, int xend) { float x, y; int ix, iy, fx; col_data buf; for (ix = xstart; ix <= xend; ++ix) { buf.xpos = ix; x = x1 + ix*(x2-x1)/(nx-1); for (iy = 0; iy < NY; ++iy) { y = y1 + iy*(y2-y1)/(ny-1); buf.ycol[iy] = fraktal(x, y, 255.0, MAX); /* Kritisk region... */ down(empty); down(mutex); *sh_mem = buf; up(mutex); up(full); /*... slutt på kritisk region. */ Forelesning 12.4.2000 Ark 19 av 29

Konsumenten Produsenten skal hente data fra produsentene og tegne dem på skjermen. Den er ferdig når alle kolonnene er tegnet opp. void konsument(void) { col_data buf; int cx, iy; for (cx = 0; cx < NX; ++cx) { /* Kritisk region... */ down(full); down(mutex); buf = *sh_mem; up(mutex); up(empty); /*... slutt på kritisk region. */ for (iy = 0; iy < NY; ++iy) { x147plot(buf.xpos, iy, buf.ycol[iy]); x147sync(); if (x147done) terminate(0); Forelesning 12.4.2000 Ark 20 av 29

Terminering void terminate(int status) { if (shmctl(sh_mem_id, IPC_RMID, 0) < 0) perror("fraksem"); if (semctl(sem_id, 0, IPC_RMID) < 0) perror("fraksem"); exit(status); Resultat Kombinasjonen semaforer/felles lager gir den beste versjonen hittil. Ant prosesser oin modsognir 1 55 s 21 s 2 55 s 10 s 3 56 s 8s 4 57 s 8s 6 58 s 8s Forelesning 12.4.2000 Ark 21 av 29

Husk! Husk at både semaforer og delt lager er en meget begrenset ressurs, og at disse ikke fjernes automatisk. Sjekking Kommandoen ipcs forteller om det er allokert noen semaforer eller delt lager: % ipcs IPC status from /dev/kmem as of Mon Apr 22 1999 T ID KEY MODE OWNER GROUP Message Queues: Shared Memory: m 0 0x53637444 --rw-r--r-- root wheel m 7901 0x00000000 --rw------- dag dag m 102 0x00000000 --rw------- dag dag m 3 0x00000000 --rw------- dag dag Semaphores: s 0 0x00000000 --ra------- dag dag s 1 0x00000000 --ra------- dag dag s 2 0x00000000 --ra------- dag dag Forelesning 12.4.2000 Ark 22 av 29

Fjerning Kommandoen ipcrm brukes til fjerning av både semaforer (opsjonen -s) og delt lager (opsjonen -m): % ipcrm -m 7901 % ipcrm -m 102 % ipcrm -m 3 % ipcrm -s 0 % ipcrm -s 1 % ipcrm -s 2 % ipcs IPC status from /dev/kmem as of Mon Apr 21 1997 T ID KEY MODE OWNER GROUP Message Queues: Shared Memory: m 0 0x53637444 --rw-r--r-- root wheel Semaphores: Forelesning 12.4.2000 Ark 23 av 29

«De spisende filosofer» Problemet med «the dining philosophers» er oppfunnet av Edsger Dijkstra i 1965. Rundt et bord sitter 5 filosofer: '$ - ~ ~ &%'$?&% ~ &% '$ '$ 6 ~ ~ &% 6 &% Hver av dem har foran seg en tallerken med spagetti og en gaffel til venstre for tallerkenen. Man trenger to gafler (ens egen og høyre sidemanns) for å spise spagetti. Hver filosof tilbringer dagen med vekselvis å tenke og å spise. De snakker aldri sammen. Problemet er å finne en algoritme som sørger for at alle filosofene får mat fra tid til annen. Forelesning 12.4.2000 Ark 24 av 29

Forsøk på løsning #define N 5 #define LEFT(x) ((x)==0? N-1 : (x)-1) #define RIGHT(x) ((x)==n-1? 0 : (x)+1) philosopher(i) /* Hva skal filosof i gjøre? */ int i; { while (TRUE) { think(); take_fork(i); take_fork(right(i)); eat(); put_fork(i); put_fork(right(i)); Rutinen take fork okkuperer angitte gaffel hvis den er ledig; hvis ikke, blir prosessen blokkert. Rutinen put fork frigjør angitte gaffel. Vurdering Kan føre til vranglås. Vi kan risikere at alle filosofene plukker opp sin gaffel og så sulter i hjel mens de venter på at en annen skal legge fra seg sin. Konklusjon: Ubrukelig. Forelesning 12.4.2000 Ark 25 av 29

Et nytt forsøk på løsning Ved å gjøre spisingen til en kritisk region, sikrer vi at filosofen alltid får tak i begge gafler. #define N 5 #define LEFT(x) ((x)==0? N-1 : (x)-1) #define RIGHT(x) ((x)==n-1? 0 : (x)+1) semaphore mutex = 1; philosopher(i) /* Hva skal filosof i gjøre? */ int i; { while (TRUE) { think(); down(&mutex); /* Lag en kritisk region... */ take_fork(i); take_fork(right(i)); eat(); put_fork(i); put_fork(right(i)); up(&mutex); /*...kritisk region. */ Vurdering + Vil ikke gå i vranglås. Kun én filosof kan spise av gangen. Konklusjon: Egentlig ubrukelig. Forelesning 12.4.2000 Ark 26 av 29

Enda et forsøk Vi kan la en sulten filosof sjekke om gaffelen til høyre sidemann er ledig; hvis den ikke er det, legger filosofen fra seg sin egen gaffel og tenker litt til. #define N 5 #define LEFT(x) ((x)==0? N-1 : (x)-1) #define RIGHT(x) ((x)==n-1? 0 : (x)+1) philosopher(i) /* Hva skal filosof i gjøre? */ int i; { while (TRUE) { think(); take_fork(i); if (free_fork(right(i)) { /* Sjekk om ledig. */ eat(); put_fork(right(i)); put_fork(i); (Her vil kallet på free fork returnere med 0 (= FALSE) hvis gaffelen ikke er ledig. Hvis den er ledig, blir den tatt, så vi trenger ikke kalle på take fork.) Forelesning 12.4.2000 Ark 27 av 29

Vurdering + Denne løsningen vil stort sett gå bra, særlig hvis vi vet at tiden filosofene tenker, varierer tilfeldig. I meget spesielle tilfelle oppstår det utsulting. Filosofene vil ta opp og legge ned gafler i takt uten at noen får spise. Konklusjon: Brukbar, med mindre vi ønsker 100% sikkerhet. En løsning som virker Den kommer neste uke. Forelesning 12.4.2000 Ark 28 av 29

Oppsummering Teknikk Synk Data Spesielt UNIX filer UNIX rør Forutsetter samme urprosess Kan ikke alltid brukes. Delt lager Semaforer Forelesning 12.4.2000 Ark 29 av 29