PROCESSPROGRAMMERING
Föreläsning 6 (19.3.2007)
Innehåll:
-Producent – konsument problemet
-Förmedling av fildeskriptorer
Jonny Karlsson 19.3.2007
En producent och en konsument
Konsumenten måste kunna konsumera alla tal som producerats av producenten även
om produktionen går snabbare än konsumtionen.
Lösning: användning av semaforer (utan semaforskydd skrivs minnesbufferns poster
över innan konsumenten hinner läsa alla poster.
Jonny Karlsson 19.3.2007
En producent och en konsument
Det behövs 2 heltalssemaforer
• TOM initialiseras till N=antalet platser i buffern
• FULL initialiseras till 0
Pseudokod för producentprocessen:
/* delat minne */
int buffer[N], in=0, ut=0;
/*semaforer*/
initsemaphore TOM = N;
initsemaphore FULL = 0;
while(1)
{
producera(tal);
P(TOM);
buffer[in] = tal;
in = (in + 1) % N;
V(FULL);
}
Jonny Karlsson 19.3.2007
En producent och en konsument
Pseudokod för konsumentprocessen:
while(1)
{
P(FULL);
tal = buffer[ut];
ut = (ut + 1)%N;
V(TOM);
}
Jonny Karlsson 19.3.2007
Flera konsumenter och producenter
Problem:
Alla producenter använder samma index-variabel för att placera
heltal i kön. Alla konsumenter använder samma index-variabel för
att hämta heltal från kön.
Lösning:
Använd en binär semafor för att kontrollera att endast en
producent kommer åt kön/minnesbuffern på en samtidigt.
Använd likaså en binär semafor för att kontrollera att endast en
konsument får läsa värden ur kön samtidigt.
Jonny Karlsson 19.3.2007
Flera konsumenter och producenter
Pseudokod för producent-processerna:
/* delat minne */
int buffer[N],in=0,ut=0;
/* 4 semaforer /*
initsemaphore TOM=N;
initsemaphore FULL=0;
initsemaphore SEMIN=1;
initsemaphore SEMUT=1;
while(1)
{
producera(tal);
P(TOM);
P(SEMIN);
buffer[in]=tal;
in=(in+1)%N;
V(SEMIN);
V(FULL);
}
Jonny Karlsson 19.3.2007
Flera konsumenter och producenter
Pseudokod för producent-processerna:
while(1)
{
P(FULL);
P(SEMUT);
tal = buffer[ut];
ut=(ut+1)%N;
V(SEMUT);
V(tom);
konsumera(tal);
}
För mer detaljerad beskrivning av konsument-producent probemet
se föreläsningskompendium sid 29-31
Jonny Karlsson 19.3.2007
Förmedling av fildeskriptorer
En process skapar en fildeskriptor och den öppna fildeskriptorn skickas över till en/flera
andra processer.
Mycket användbart vid programmering av klient-server applikationer.
Mycket typiskt går det till så att serverprocessen gör allt som behövs för att öppna en fil
och sedan skickas den öppna fildeskriptorn över till anropande klientprocesser.
Jonny Karlsson 19.3.2007
Filhantering
Kerneln använder 3 datastrukturer för filhantering och relationerna mellan dessa
bestämmer hurdan effekt en process har på en annan vid delning av öppna
fildeskriptorer:
•Processtabell (process table)
•Filtabell (file table)
•v-nod tabell (v-node table)
Varje process är associerad med en processtabell vilken innehåller en tabell med
öppna fildeskriptorer för varje process. Associerade med varje fildeskriptor är:
•Flaggor för fildeskriptorerna
•En pekare till en filtabell
Kerneln uppehåller en filtabell för alla öppna filer. Varje filtabell innehåller:
•Filstatusflaggan för filen (read, write, append, nonblocking, m.m.)
•Nuvarande ”file offset” (bestämmer var följande read/write operation startar)
•En pekare på v-nod tabellen för filen
Jonny Karlsson 19.3.2007
Filhantering
Varje öppen fil har en v-nod tabell. V-noden innehåller information om filtypen och
pekare på funktioner som hanterar filen. V-nod tabellen innehåller även I-nod
information vilket berättar bl.a. filägaren och filstorleken.
Jonny Karlsson 19.3.2007
Fildelning
Två processer delar en öppen fil genom att använda två sparata filtabeller
(båda processerna skapar en egen fildeskriptor med open())
Jonny Karlsson 19.3.2007
Fildelning
Två processer delar en öppen fil genom att den ena processen skapar
fildeskriptorn och överför denna till den andra processen
Jonny Karlsson 19.3.2007
Överföring av fildeskriptorer
Det man egentligen vill åstadkomma vid överföring av fildeskriptorer är att två eller flere
processer delar samma filtabell.
Det som egentligen sker tekniskt är att man överför en pekare till en filtabell från en
process till en annan. Dena pekare får första tillgängliga deskriptorvärde.
Observera att båda processerna har inte samma deskriptornummer eftersom de
fortfarande har skilda processtabeller.
Om ena processen stänger sin fildeskripor är filen ändå fortfarande öppen för den andra
processen.
Jonny Karlsson 19.3.2007
Att sända en fildeskriptor
En fildeskriptor kan sändas över till en annan process genom en rörledning genom att
använda ioctl() funktionen:
ioctl(pd[1], I_SENDFD, deskr);
pd[1]
Deskriptorn för skrivändan i den rörledning genom vilken deskriptorn
skall skickas.
I_SENDFD
Kommandoflagga som berättar att en deskriptor skall skickas.
deskr
Den fildeskriptor som skall skickas.
Jonny Karlsson 19.3.2007
Att ta emot en fildeskriptor
En fildeskriptor kan tas emot från en annan process från en rörledning genom att
använda ioctl() funktionen:
ioctl(pd[1], I_RECVFD, &deskrpek);
pd[0]
Deskriptorn för läsändan i den rörledning varifrån deskriptorn
skall tas emot.
I_RECVFD
Kommandoflagga som berättar att en deskriptor skall skickas.
deskrpek
En pekare på en post av typen struct strrecvfd (Se nästa slide)
Jonny Karlsson 19.3.2007
Att ta emot en fildeskriptor
struct strrecvfd
{
int fd;
uid_t uid;
gid_t gid;
char fill[8];
}
//den nya deskriptorn
//användar ID för avsändaren
//grupp ID för avsändaren
Jonny Karlsson 19.3.2007