Title: PROCESSPROGRAMMERING
1PROCESSPROGRAMMERING
- Föreläsning 6 (4.10.2005)
- Innehåll
- - Förening av dataströmmar
- Blockerande I/O multiplexering
- Icke blockerande I/O multiplexering med
signalering
2Förening av dataströmmar
- Systemanrop i UNIX kan delas in i två kategorier
- Långsamma systemanrop Kan blockera en process för
alltid - Övriga systemanrop Blockerar ej
- Exempel på systemanrop som kan blockera för
alltid - Läsoperationer, om data saknas
- Skrivoperation, om data inte kan accepteras
- Öppningsoperationer (t.ex. FIFO)
3Förening av dataströmmar
- Exempel Läsning av en rörlednings dataström
som visas på skärmen
while(..) read(pd0, buf, sizeof(buf)) print
f(s, buf)
4Förening av dataströmmar
- Exempel2 Läsning av två rörledningars
dataströmmar som förenas och visas på
bildskärmen
Lösning1 Blockerande I/O multiplexering med
systemanropet select() Lösning2 Icke-blocker
ande I/O multiplexering med signalering
5Blockerande I/O multiplexering
Systemanropet select() include
ltsys/types.hgt include ltsys/time.hgt include
ltunistd.h int select(int maxdeskr, fd_set
readDeskrSet, fd_set writeDeskrSet, fd_set
exceptDeskrSet, struct timeval tvptr)
maxdeskr Det maximala deskriptorvärdet för de
deskriptorer som skall lyssnas på
1 readDeskrSet Pekare på en post innehållande de
deskriptorer som skall lyssnas på när man
kollar om en deskr. är redo för
avläsning. writeDeskrSet Pekare på en post
innehållande de deskriptorer som skall lyssnas
på när man kollar om en deskr. är redo för
skrivning.
6Blockerande I/O multiplexering
- exeptDeskrSet Pekare på en post innehållande de
deskriptorer som skall lyssnas - på när man kollar om en deskr. har hamnat i
ett undantagstillstånd (t.ex. uppstått ett fel) - tvptr En post som definierar den tid select()
skall blockera processen och vänta på en aktiv
deskriptor innan programmet går vidare - struct timeval
-
- long tv_sec /sekunder/
- long tv_usec /millisekunder/
-
- Returnerar Returnerar antalet aktiva deskriptorer
(antalet deskriptorer som är redo för
läsning/skrivning eller förorsakat ett fel
7Blockerande I/O multiplexering
- Argumenten som ges till systemanropet select()
berättar för kerneln - vilka deskriptorer vi är intresserade av
- vilka tillstånd hos varje deskriptor vi är
intresserade av (läsa, skriva, undantag) - Hur länge vi vill vänta (inte alls, en viss tid
eller för alltid) - När select() returnerar berättar kerneln för oss
- Det totala antalet deskriptorer som är klara
- Vilka deskriptorer som är klara för vilket
tillstånd (läsa, skriva, undantag) - Om select returnerar ett värde gt 0 vet vi att en
eller flera deskriptorer är redo för ett - visst tillsånd och vi kan därefter kalla på
lämpligt systemanrop (oftast read eller write) - och samtidigt vara säkra på att processen inte
blockeras
8Blockerande I/O multiplexering
- Det finns fyra definierade macron för hantering
av fd_set poster - FD_ZERO(fd_set fdset) Tömmer posten
- FD_SET(int deskr, fd_set fdset) Sätter till en
deskriptor i posten som skall övervakas - FD_CLR(int deskr, fd_set fdset) Tar bort en
deskriptor ur posten - FD_ISSET(int deskr, fd_set fdset) Blir true
om deskriptorn man ger som första parameter
är redo
9Blockerande I/O multiplexering
- Principen för användning av fd_set poster och
select() - Deklarera deskriptorer och fd_set poster
- Nolla fd_set posterna med FD_ZERO()
- Addera alla deskriptorer man vill testa till en
fd_set post med FD_SET() - Låt select() vänta på aktiva deskriptorer
- Testa vilken deskriptor som blev klar med
FD_ISSET() - Läs data från respektive klar deskriptor
- Första parametern i select() är ett
avgränsarvärde som definierar det maximala värdet
för - en deskriptor som skall övervakas 1.
- ? Exempel 1
10Icke-blockerande I/O multiplexering med
signalering
- Signaler kan utnyttjas för att uföra asynkron
multiplexering av dataströmmar. - Behövs två inställningar för varje deskriptor som
skall övervakas - Deskriptorn måste sättas i icke-blockerande läge
- Kerneln skall generera signalen SIGPOLL när en
deskriptor som övervakas blir redo. - Systemanropet fcntl() kan användas för att ändra
läget hos en deskriptor - fcntl(deskr, F_SETFL, O_NONBLOCK) //hissar
flaggen O_NONBLOCK hos //deskriptorn deskr - För mera information om systemanropet fcntl, se
man-fil.
11Icke-blockerande I/O multiplexering med
signalering
- Systemanropet ioctl() kan användas för att
berätta åt kerneln att generera en viss signal - vid ett visst tillstånd hos en övervakad
deskriptor - ioctl(deskr, I_SETSIG, S_RDNORM) //genererar
SIGPOLL när en deskriptor är redo //för
avläsning - För mera information om systemanropet ioctl, se
man-fil. - När signalen SIGPOLL genererats måste alla
övervakade deskriptorer testas (t.ex. läsas - med read) eftersom man inte kan veta vilken
deskriptor som orskakat SIGPOLL. - Eftersom read inte i detta fall får blockera
processen om inget data finns att hämta, - måste läsdeskriptorn vara i oblockerande läge.
- SIGPOLL signalen måste fångas upp, annars avbryts
programmet när den första - deskriptorn blir aktiv
12Icke-blockerande I/O multiplexering med
signalering
- Systemanropet pause() används för att frysa
processen tills en eller flera deskriptorer blir - aktiva.
- Principen för asynkron multiplexering
- Deklarera och skapa deskriptorerna
- Definiera en signaluppfångare för signalen
SIGPOLL - Ställ in deskriptorerna i icke-blockerande läga
- Aktivera signalen SIGPOLL för varje aktiv
deskriptor - Vänga på signalen (som informerar om att en
deskriptor blivit aktiv) med pause() - Testa varje deskriptor genom att försöka läsa ur
dem. - ? Exempel 2