Trådar och Multiprocessorer
Föreläsning 6
Trådar och multiprocessorer
 Hur skriver man program som hanterar många saker samtidigt,
t.ex. en web-server som hanterar många samtidiga begäran från
olika klienter?
 Hur kan vi bygga snabbare/kraftfullare datorer?
 Hur kan vi lösa större beräkningsproblem?
Trådar – en programmeringsmodell
Trådar i Pthreads, Solaris och Windows
Multiprocessorer
Behovet av synkronisering
Kap: 2.2-2.3, 8.1-8.2
OS Föreläsning 6,
Multiprocessorer och trådar
2
Trådar (threads)
Trådar
- en programmeringsmodell
Att tillåta flera processer att exekvera på en
dator ger flera fördelar:
 Tillåter flera samtidiga användare/tasks
 Kan överlappa beräkning och I/O
Återanvänd idén:
- många applikationer kan modelleras
enklare/bättre om man har ”processer” i
processen
OS Föreläsning 6,
Multiprocessorer och trådar
4
Exempel på program som blir lättare att skriva
med trådar
Simuleringar
 Modellerar ofta flera parallella processer
 Ex: simulering av del av Internet med
användardatorer, routrar etc.
Serverapplikationer
 Ex: Webb-server, spelserver
Men även många vanliga interaktiva
applikationer
 Ordbehandlare, kalkylprogram...
 Program med flera fönster, t.ex. grafisk debugger
OS Föreläsning 6,
Multiprocessorer och trådar
5
Processer och trådar
Text (kod) Heap (data)
Register
Filer
Stack
Text (kod) Heap (data)
Filer
Register
Register
Register
Stack
Stack
Stack
tråd
Enkeltrådad process
(det vi sett hittills)
Multitrådad process
OS Föreläsning 6,
Multiprocessorer och trådar
Trådarna delar kod, heap
och filer
6
Vad är en tråd?
En tråd kan ses som en virtuell CPU
eller lättviktsprocess
 Programräknare
 Register
 Stack
En process kan ses som en virtuell maskin
 Adressrymd (minne)
 En eller flera trådar
OS Föreläsning 6,
Multiprocessorer och trådar
7
Trådar
- fördelar
 Responstid – hantering av blockerande systemanrop
 En multitrådad interaktiv/server applikation kan svara på
input även om delar (någon/gra trådar) är blockerade eller
utför någon tidskrävande operation
 Dela resurser
 Flera aktiviteter kan dela kod, data etc. i en process
 Ekonomi
 Trådar kräver inte lika mycket egna resurser och är
enklare/billigare att skapa och att switcha mellan
(ex: Solaris 2 process/tråd: tid för att skapa 30/1, context switch 5/1)
 Utnyttja datorer med flera processorer
 Trådar kan (enkelt) utnyttja datorarkitekturer med flera
processorer för att exekvera snabbare
OS Föreläsning 6,
Multiprocessorer och trådar
8
Var implementerar man trådar
- i OS-kärnan eller i användarläge (user-space)
 I användarläge
 Trådoperationerna är biblioteksrutiner
 Schemaläggningen görs av run-time system
 Trådhantering, skapande/dödande omhändertagande av
terminerade trådar etc. sköts via biblioteksrutiner och
run-time system
 I kärnan
 Trådoperationerna är systemanrop
 Schemaläggningen görs av kärnan
 trådhantering, skapande/dödande omhändertagande av
terminerade trådar etc. sköts via systemanrop och kärnan
OS Föreläsning 6,
Multiprocessorer och trådar
9
Trådar i kernel-space resp. user-space
Run-time
system
Run-time
system
Trådtabell
User-space
OS-kärna
User-space
Process
tabell
User threads (användartrådar)
OS-kärna
Process
tabell
Tråd
tabell
Kernel threads
OS Föreläsning 6,
Multiprocessorer och trådar
10
Om trådar i användarläge
Schemaläggning, trådbyte sköts utan
systemanrop
 Färre context switchar ger bättre prestanda
Kärnan vet ej om att det finns trådar
 Kan användas även med gamla operativsystem
Schemaläggning i två nivåer
 Kärnan bestämmer vilken process som skall köra
 Trådbiblioteket bestämmer vilken tråd inom
processen som kör
OS Föreläsning 6,
Multiprocessorer och trådar
11
Mera om trådar i användarläge
Nackdelar med trådar i användarläge
 Blockeras en tråd så blockeras hela processen dvs.
alla trådar i processen
 Schemaläggning är oftast icke avbrytande (nonpreemptive)
 Ingen sann parallellitet på multiprocessorer
OS Föreläsning 6,
Multiprocessorer och trådar
12
Trådar i kärnan
Fördelar
 Kan ha preemptiv schemaläggning
 Om en tråd blockeras kan en annan tråd i samma
process schemaläggas
 Kärnan kan utnyttja trådar för att själv bli
effektivare
 Kan schemaläggas på olika processorer i en multiprocessor – utnyttja sann parallellitet
Nackdelar
 Trådoperationer är systemanrop - tar längre tid
att utföra och kostar mer t.ex i context switch
OS Föreläsning 6,
Multiprocessorer och trådar
13
Hybrider
Hybridformer är vanligast i moderna
operativsystem
 Kärnan tillhandahåller ett visst antal trådar
 En eller flera användartrådar mappas på en eller
flera trådar i kärnan
OS Föreläsning 6,
Multiprocessorer och trådar
14
Att mappa trådar
- användartrådar på kärntrådar
Flera användatrådar på en
kärntråd
ex: Solaris ”green threads”
En användartråd på en kärntråd
ex: Windows 2000, NT
Många användartrådar på en
grupp av kärntrådar
ex: Solaris, HP-UX, True64 UNIX
OS Föreläsning 6,
Multiprocessorer och trådar
15
Några praktiska funderingar kring
trådar och
Systemanrop
Trådpooler
exec, fork
Signaler, kancellering
Trådar och systemanrop
Exempel: En webserver hämtar en begäran åt
gången och utför den
 Om en begäran medför diskaccess kan servern inte
ta emot en ny begäran förr än dess att
diskaccessen är klar
 Slöseri av flera skäl
 Om man har flera diskar kan de arbeta parallelt
 Om efterföljande begäran inte behöver diskaccess är det
onödigt att de skall vänta
 Låt servern starta en ny tråd för varje begäran
OS Föreläsning 6,
Multiprocessorer och trådar
17
Trådar och systemanrop
Trådad server
Otrådad server
while ( True ) {
recieve(&request);
handle(request);
}
while ( True ) {
recieve(&request);
create_thread(&handle,request);
}
OS Föreläsning 6,
Multiprocessorer och trådar
18
Hur många trådar kan man skapa?
- trådpooler
Oftast finns en övre begränsning
Hur gör vi i exemplet med webb-servern?
 Ha en pool av trådar
 Den tråd som tar emot en begäran kan göra så här:
1 Om det finns ledig tråd i trådpoolen
2 Ta emot begäran
3 Väck en tråd ur trådpoolen som behandlar begäran
4 Börja om från 1
 Den tråd som väcks behandlar sin begäran och
lägger sig sedan att sova i trådpoolen
OS Föreläsning 6,
Multiprocessorer och trådar
19
Trådar som exekverar exec eller fork
 En tråd exekverar fork
 Två val:
1. Den nya processen får en tråd
2. Den nya processen blir en exakt kopia av den
gamla med lika många trådar
 En tråd exekverar exec
 Vanligast är att hela processen, dvs alla trådar,
börjar exekvera det nya programmet
OS Föreläsning 6,
Multiprocessorer och trådar
20
Att döda (kancellera) trådar
Inte helt problemfritt...
Vad gör man om:
 Tråden har resurser knutna till sig – lämnas de till
- processen?
- tar OS:et tillbaka dem?
 Tråden håller på med något som andra trådar
väntar på, eller kan komma att vänta på
OS Föreläsning 6,
Multiprocessorer och trådar
21
Feltolerans
Går det att bygga feltoleranta system genom
att utnyttja flera trådar i en process?
Frågan att fundera över:
 Överlever systemet/processen att en tråd får
t.ex ett exekveringsfel som segmentation fault
eller bus error?
Har man behov av att systemet överlever
hårda fel kan det vara bättre att bygga på
processer som ”isoleras bättre” från varandra
OS Föreläsning 6,
Multiprocessorer och trådar
22
Att skicka signaler till trådar
Om man skickar en signal till en tråd vad gör
man då?
 Levererar signalen bara till den berörda tråden
 Levererar signalen till varje tråd i processen
 Levererar signalen till några utvalda trådar i
processen
 Utser en speciell tråd att ta hand om alla signaler
(Solaris)
OS Föreläsning 6,
Multiprocessorer och trådar
23
Exempel på trådimplementationer
Pthreads
Solaris2
Windows 2000
Java
Pthreads
POSIX standard som beskriver gränssnitt
och beteende (inte hur det ska implementeras)
Trådbibliotek och run-time system på
användarnivå
Allmänt använt på olika UNIX system
OS Föreläsning 6,
Multiprocessorer och trådar
25
Pthread exempel
HELT UTAN FELKONTROLLER...
#include <pthread.h>
#include <stdio.h>
int sum = 0; // shared variable
void runner(char *);
void runner(char *arg1)
{
int upper = atoi(arg1);
int i;
if(upper <= 0)
{
printf(”talet måste vara > 0\n”);
pthread_exit(1);
}
void main(int argc, char *argv[])
{
pthread_t tID;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tID, &attr,
runner, argv[1]);
pthread_join(tID, NULL);
printf(”Summa: %d\n”, sum);
}
sum = 0;
for(i=1; i <= upper; i++)
sum += i;
pthread_exit(0);
}
OS Föreläsning 6,
Multiprocessorer och trådar
26
Solaris2
Tre nivåer av trådar
 Tråd på användarnivå:
 trådId, register, stack och prioritet
 LWP – light weight process
 Datastruktur i kärnan med
- registeruppsättning för den användartråd som
exekverar i LWPn, minne och ”accounting” info
 Tråd i kärnan
 Liten datastruktur med liten stack
 Pekare till ansluten LWP
OS Föreläsning 6,
Multiprocessorer och trådar
27
Solaris2 forts.
Användartrådar
Processer
(tasks)
LWP
Kärntrådar
Kärnan
Processorer
OS Föreläsning 6,
Multiprocessorer och trådar
28
Kan man tjäna något på att använda
trådar?
SUN designade om telnet-servern till att
använda trådar för att hantera telnetförbindelser
På en större server kunde man öka antalet
samtidiga uppkopplingar från
några hundra till några tusen
OS Föreläsning 6,
Multiprocessorer och trådar
29
Windows 2000
 Ett-till-ett mappning av användartrådar till
kärntrådar
 Flera trådar i en process (tråd
schemaläggningsenhet)
 Bibliotek för ”fibers” – möjlighet att köra flera
trådar i en användartråd
 Datastrukturer





Tråd ID
Registeruppsättning
Användarstack (för exekvering i user-mode)
Kärnstack (för exekvering i kernel-mode)
Privat dataarea
OS Föreläsning 6,
Multiprocessorer och trådar
30
JAVA
Implementerar trådar i den virtuella
maskinen
 Svårt att klassificera som användar- eller
kärntrådar
Ett sätt att skapa trådar är genom att
 Ärva från Thread klassen
 Överlagra run metoden i Thread klassen
OS Föreläsning 6,
Multiprocessorer och trådar
31
JAVA exempel
HELT UTAN FELKONTROLLER...
class Summation extends Thread
{
public Summation(int n) {
upper = n;
}
public void run() {
int sum = 0;
if(upper > 0)
for(int i = 1; i <= upper; i++)
sum += i;
}
public class ThreadTester
{
public static void
main(String[] args) {
Summation thrd = new
Summation(
Integer.parseInt(args[0]));
thrd.start();
}
}
private int upper;
}
OS Föreläsning 6,
Multiprocessorer och trådar
32
Multiprocessorer
Hur bygger vi snabbare datorer?
Snabbare datorer
Möjliga vägar:
Öka klockfrekvensen
 Minska storleken pga fysiska begränsningar
(ljushastigheten) när det gäller att kunna
distribuera klockan
 Problem med värmeproduktion
Öka antalet processorer
 Multiprocessordatorer (hårt kopplade)
 Datorer i nätverk
 Flera processorer på ett chip
OS Föreläsning 6,
Multiprocessorer och trådar
34
Multiprocessorer
CPU
CPU
CPU
CPU
CPU
CPU
CPU
CPU
Minne
Minne
I/O
Buss eller nät
I/O
Minne
Minne
OS Föreläsning 6,
Multiprocessorer och trådar
35
Multiprocessorer
- intressanta designval/parametrar
Sammanbindningsnät
 Buss – begränsar antalet processorer till ~20
 Nät: crossbar, switch
- antal procesorer upp mot 1000
 Fördröjningstid i nätet vid minnessaccess
- uniform/icke-uniform, kort/lång
Delat minne eller privat
 Delat minne – allt minne kan accessas direkt av alla
processorer – anses ofta enklare att programmera
 Privat minne – kommunikation med meddelanden
OS Föreläsning 6,
Multiprocessorer och trådar
36
Cachning i multiprocessorer
CPU
CPU
CPU
cache
cache
cache
I/O
Minne
Minne
Cachear minskar lasten på
sammanbindningsnätet/bussen
Men:
- Hur håller man informationen
konsistent?
- False-sharing problematik
OS Föreläsning 6,
Multiprocessorer och trådar
37
Schemaläggning på multiprocessorer
Frågan är inte bara när utan också var en
tråd eller process skall köras
 För lastbalansering och rättvisa är det bäst att
köra en tråd varsomhelst (en ready-kö)
 För effektivt utnyttjande av processorernas
cacheminne/sidhantering/TLB är det bäst att köra
en tråd på samma processor som förra gången (en
ready-kö för varje processor)
OS Föreläsning 6,
Multiprocessorer och trådar
38
Varför trådar från samma jobb bör få
exekvera samtidigt...
Trådar från samma jobb synkroniserar ofta
 Om schemaläggaren tar ifrån en tråd dess CPU
medan den håller ett lås och
 andra trådar i den processen vill ha låset och
 systemet använder lås med busy waiting så
 kommer övriga trådar att få vänta länge
OS Föreläsning 6,
Multiprocessorer och trådar
39
Schemaläggning forts.
 Mål:




Lastdelning – ingen processor bör vara för lite/mycket lastad
Rättvis –processerna ska få sin rättmätiga del av CPU tiden
Effektivt utnyttjande av resurser
Kommunicerande processer bör få köra samtidigt!
 Varianter:
 En gemensam ready-kö
– blir lätt flaskhals men bra lastdelning
 Varje processor har egen ready-kö
- lastdelning t.ex. genom att underutnyttjade CPU:er kan
fråga andra om de har jobb som de vill bli av med
 Gängschemaläggning
OS Föreläsning 6,
Multiprocessorer och trådar
40
Gängschemaläggning (gang scheduling)
Alla trådar i en process kör samtidigt på olika
CPU:er
Alla CPU:er byter process samtidigt
Om en tråd blir BLOCKED blir dess CPU idle
(ingen annan tråd körs)
Kan kombineras med space sharing där olika
processer körs på olika grupper av CPUer
OS Föreläsning 6,
Multiprocessorer och trådar
41
Löst kopplade multiprocessorer/datorer
Sammankopplade med nät som har
förhållandevis lång fördröjning
Det finns/fanns stort intresse för ”GRIDcomputing” – beräkningar på vanliga datorer i
nät (Internet)
Problemet är att inte få för dålig prestanda
pga fördröjningar i nätet
 Olika applikationer är olika känsliga....
OS Föreläsning 6,
Multiprocessorer och trådar
42
En första titt på
- ömsesidig uteslutning och synkronisering
Behovet av ömsesidig uteslutning
Antag en gemensam ready-kö i en multiprocessor
Process
struct A
Process
struct B
Kod för att hämta en
process med prioritet i
ready kö
new = ready[i];
tmp = new -> next;
ready[i] = tmp;
Array av ready köer
med olika prioriteter
OS Föreläsning 6,
Multiprocessorer och trådar
44
Ready-kön:
Behovet av mutual exclusion
 Om två processorer samtidigt vill ta ut en ny process
ur ready-kön kan följande hända:
 Den första processorn sätter den lokala variabeln new att
peka på process struct A
 Den andra processorn sätter sin lokala variabel new att peka
på samma struct A
 Bägge processorerna sätter ready[i] att peka på process
struct B
 Bägge processorerna börjar köra samma process!
Inte bra ...
 Resultatet beror av i vilken ordning processorerna
exekverar – race-condition
OS Föreläsning 6,
Multiprocessorer och trådar
45
Ömsesidig uteslutning
- mutual exclusion
Man använder lås
 Ett lås kan vara ledigt eller upptaget
 Man kan låsa och låsa upp lås
 Om man försöker låsa ett låst lås får man vänta
till dess att den som låst det låser upp det
Med ett lås för ready-kön gör man så här
 Lås låset
 Plocka ut en process
 Lås upp
OS Föreläsning 6,
Multiprocessorer och trådar
46
Implementation av lås på
multiprocessor
lock:
test_and_set
tmp, (lock_ptr)
branch_not_zero tmp, lock
unlock: store (lock_ptr), 0
OS Föreläsning 6,
Multiprocessorer och trådar
47
Implementation av lås på
multiprocessor
test_and_set tmp, (lock_ptr) är en
maskininstruktion som
 skriver värdet 1 till minnet på adress lock_ptr
 läser in gamla värdet till registret tmp
 låser bussen så att ingen annan processor kommer
emellan
Denna instruktion kan användas till andra
typer av lås också
OS Föreläsning 6,
Multiprocessorer och trådar
48
Implementation av lås på
multiprocessor
 Om låset är låst hoppar man tillbaka och försöker igen
 Denna typ av lås kallas spin-locks och gör busy waiting
 Lämpliga på multiprocessorer, men mycket olämpliga på
en-processormaskiner
 Endast en annan process kan låsa upp låset
 Man spinner resten av time-slice
 Andra typer av lås gör processen BLOCKED om låset är
upptaget
OS Föreläsning 6,
Multiprocessorer och trådar
49
Synkronisering
Bakom kulisserna i en pipe
En pipe implementeras som en buffer i kärnan
 Finns alltid i huvudminnet
 Har en viss storlek (några sidor)
Om en process vill skriva till en pipe vars
buffer är full måste den vänta
Om en process vill läsa från en pipe vars
buffer är tom måste den vänta
Exempel på synkronisering (ofta inbyggt i
systemanrop i Unix)
OS Föreläsning 6,
Multiprocessorer och trådar
51
Bakom kulisserna i en pipe
Man måste hålla reda på hur mycket data det
finns i bufferten
Liknande problem som vid exemplet med
ready-kön
Semaforer kan användas
OS Föreläsning 6,
Multiprocessorer och trådar
52
Semaforer
En semafor är en räknare som har
operationerna
 upp: öka värdet med ett
 ner: minska värdet med ett om det ej är noll, vänta
i så fall
En semaforoperation är odelbar
 Ingen annan tråd eller process kan komma in
emellan
Väntande trådar kan läggas i kö
OS Föreläsning 6,
Multiprocessorer och trådar
53
Bakom kulisserna i en pipe med
semaforer
Två semaforer används
 ledig_plats visar mängden ledigt utrymme
 färdigt_data visar mängden färdigt data
Varje operation antas för enkelhets skull
skriva eller läsa en byte
OS Föreläsning 6,
Multiprocessorer och trådar
54
Bakom kulisserna i en pipe med
semaforer
skriv(data) {
ner(ledig_plats)
lägg data i buffer
uppdatera skrivpekare
upp(färdigt_data)
}
läs() {
ner(färdigt_data)
ta ut data ur buffer
uppdatera läspekare
upp(ledig_plats)
returnera data
}
OS Föreläsning 6,
Multiprocessorer och trådar
55
Behov av synkronisering och
ömsesidig uteslutning
Synkronisering och ömsesidig uteslutning
behövs också i vanliga en-processors system!
Viktigt och klurigt problem att lösa
Gör man fel får man ofta fel som är
sporadiska och svåra att hitta...
OS Föreläsning 6,
Multiprocessorer och trådar
56
Summering
– vad vi pratat om idag
Trådar
Multiprocessorer
En första titt på synkronisering och
ömsesidig uteslutning
OS Föreläsning 6,
Multiprocessorer och trådar
57
Nästa föreläsning
Interprocesskommunikation – IPC
Remote Procedure Call – RPC
Distribuerade system
Distribuerade filsystem
OS Föreläsning 6,
Multiprocessorer och trådar
58