Processer og koordinering.. fortsat dopsys 1
Betingelsesvariabler (Condition variables).. hukommelsesløs variant af semaphorer: Atomare operationer: Signal bruges til at sende et signal. Wait bruges til at vente på et signal. signal(c): if anyblocked(c) then unblockone(c) wait(c): block(c).. designet til synkronisering af processer ifm. monitors. condition variable c; cobegin p1:... wait(c);... // p2:... signal(c);...... coend; dopsys 4
Betingelsesvariabler (Condition variables).. hukommelsesløs variant af semaphorer: Atomare operationer: Signal bruges til at sende et signal. Wait bruges til at vente på et signal. signal(c): if anyblocked(c) then unblockone(c) wait(c): block(c).. designet til synkronisering af processer ifm. monitors. condition variable c; cobegin p1:... wait(c);... // p2:... signal(c);...... coend; Farligt hvorfor? dopsys 5
Monitors (Hoare, 1974).. abstraktionsmekanisme, beskytter tilgang til delte resurser: Monitor komponenter: Data - resursens tilstand Procedurer - tilgang til resursens data. Egenskaber: Tilgang til data kan kun ske via monitor-procedurer. Monitor-procedurer udføres med gensidig udelukkelse. Bagvedliggende begreb: Abstrakte datatyper. Central intuition: at være inde i monitoren eller ej. dopsys 6
Brug af monitor Forløb: Monitor bruges af p 1 og p 2, hvor p 1 kræver betingelse som p 2 skaber dopsys 7
Brug af monitor x_is_positive Forløb: Monitor bruges af p 1, som udfører et eller andet arbejde og på et tidspunkt kræver at x er ikkenegativ. Men kun g kan sikre dette: wait dopsys 8
Brug af monitor Forløb: p 1 er i waittilstand, dvs. p 1 er blokeret på betingelsesvariablen x_is_positive dopsys 9
Brug af monitor x_is_positive Forløb: på et eller andet tidspunkt agerer p 2, og kalder g som sender det ønskede signal dopsys 10
Brug af monitor Forløb: p 1 modtager signalet og kan fortsætte dopsys 11
[Click] A. Kun p 1 kan køre B. Kun p 2 kan køre C. Både p 1 og p 2 kan køre, og det er et problem D. Både p 1 og p 2 kan køre, og det er OK E. Det er en fejl at vi overhovedet er kommet i denne situation (hvad har vi glemt?) Forløb: men hvad er situationen nu? dopsys 12
Eksempel: Producer-Consumer.. behov for synkronisering omkring fyldt og tom buffer. monitor BoundedBuffer char buffer[n]; int nextin=0, nextout=0, count=0; condition notempty, notfull;.. // insert,remove,.. Hvilken proces fortsætter lige efter signal? Kunne man vælge anderledes? insert(char data) if (count==n) notfull.wait; buffer[nextin] = data; nextin = (nextin+1) % n; count = count + 1; notempty.signal; remove(char data) if (count==0) notempty.wait; data = buffer[nextout]; nextout = (nextout+1) % n; count = count - 1; notfull.signal; dopsys 13
[Q/A] Er et Javaobjekt en monitor? = dopsys 14
spørgsmål om synkronisering? dopsys 15
Implementation af Processer dopsys 16
Re: Processer Software der afvikles på maskinen = samling af samtidige sekventielle processer Proces = et program under afvikling data data proces-struktur SP A PC A stack program SP B PC B stack program Billedet af processer skal nu udbygges Proces A Proces B dopsys 17
Processer.. implementeres af operativsystemskernen: OS-kernens funktioner: Proces- og tråd-håndtering. Interrupt- og trap-håndtering. Resurse-håndtering. Input/output. dopsys 18
Process Control Block (Descriptor).. anvendes til repræsentation af processer i OS kernen: State vector: Tilstrækkelig information til at genoptage afvikling af processen. Proces status: Running: afvikles på CPU. Ready: venter på CPU. Blocked: venter på anden resurse... Process control block (PCB) typisk forbundet via et antal lister og køer. dopsys 19
Proces-tilstand.. skelnen mellem active eller suspended:.. understøtter håndtering af processen (fx opstart og debugging). dopsys 20
Eksempel: Linux /* sched.h */ struct task_struct long state; /* -1 unrunnable, 0 runnable, >0 stopped */... pid_t pid;... struct task_struct *p_opptr, *p_pptr,... /* tss for this task */ struct thread_struct tss; ; /* filesystem information */ struct fs_struct *fs; /* open file information */ struct files_struct *files; /* memory management info */ struct mm_struct *mm; /* processor.h */ struct thread_struct unsigned short back_link, blh; unsigned long esp0; unsigned short ss0, ss0h; unsigned long esp1; unsigned short ss1, ss1h; unsigned long esp2; unsigned short ss2, ss2h; unsigned long cr3; unsigned long eip; unsigned long eflags; unsigned long eax,ecx,edx,ebx; unsigned long esp; unsigned long ebp; unsigned long esi; ; unsigned long edi; dopsys 21
Proces-operationer.. ændrer på processers status. Typiske operationer: Create etablerer en ny proces. Destroy fjerner processer. Suspend ændrer status til suspenderet. Activate ændrer status til aktiv. Operationer modificerer også proceslister / køer: Ready List processer med ready status. Status Lister lister af processer som er blokerede på resurser. dopsys 22
Create Create(s0, m0, pi) p = Get_New_PCB(); pid = Get_New_PID(); p->id = pid; p->cpu_state = s0; p->memory = m0; p->priority = pi; p->status.type = ready_s; p->status.list = RL; p->creation_tree.parent = self; p->creation_tree.child = NULL; insert(self->creation_tree.child, p); insert(rl, p); Schedule dopsys 23
Suspend Suspend(pid) p = Get_PCB(pid); s = p->status.type; if ((s==blocked_a) (s==blocked_s)) p->status.type = blocked_s; else p->status.type = ready_s; if (s==running) cpu = p->processor_id; p->cpu_state = Interrupt(cpu); Scheduler(); dopsys 24
Activate Activate(pid) p = Get_PCB(pid); if (p->status.type == ready_s) else p->status.type = ready_a; Scheduler(); p->status.type = blocked_a; dopsys 25
Destroy(pid) Destroy p = Get_PCB(pid); Kill_Tree(p); Scheduler(); Kill_Tree(p) for (each q in p->creation_tree.child) Kill_Tree(q); if (p->status.type == running) cpu = p->processor_id; Interrupt(cpu); Remove(p->Status.List, p); Release_all(p->Memory); Release_all(p->Other_Resources); Close_all(p->Open_Files); Delete_PCB(p); dopsys 26
spørgsmål om implementation af processer? dopsys 27
Tråde.. skelnen mellem udførelsesdelen (control flow) og resursedelen af en proces: Fordele: Tråd-elementer: Registre Programtæller Stack Proces-elementer: Skift mellem tråde kræver ikke fuldt context-switch. Kommunikation er nemt da resurser (lager) deles. Simpel programmeringsmodel. Lager (adresserum) Åbne filer dopsys 28
POSIX Tråde: Unix OS dopsys 29
Eksempel: Enkelt-trådet program int A(void) int i; B(NULL); for (i=0; i<10; i++) printf("a\n"); sleep(1); return 0; int main(int argc,char *argv[]) A(); return 0; #include <stdio.h> void B(void *arg) int i; for (i=0; i<10; i++) printf("b\n"); sleep(2); dopsys 30
Eksempel: Enkelt-trådet program int A(void) int i; B(NULL); for (i=0; i<10; i++) printf("a\n"); sleep(1); return 0; int main(int argc,char *argv[]) A(); return 0; #include <stdio.h> void B(void *arg) int i; for (i=0; i<10; i++) printf("b\n"); sleep(2); Hvad udskriver programmet? dopsys 31
Eksempel: Flertrådet program int threada(void) pthread_t threadb; int i; pthread_create(&threadb,null, threadb,null); for (i=0; i<10; i++) printf("\n"); sleep(1); pthread_join(threadb,null); return 0; int main(int argc,char *argv[]) threada(); return 0; void* threadb (void *arg) int i; for (i=0; i<10; i++) printf("\n"); sleep(2); return NULL; %>./threadab %> dopsys 32
[Click] int threada(void) pthread_t threadb; int i; pthread_create(&threadb,null, threadb,null); for (i=0; i<10; i++) printf("\n"); sleep(1); pthread_join(threadb,null); return 0; int main(int argc,char *argv[]) threada(); return 0; void* threadb (void *arg) int i; for (i=0; i<10; i++) printf("\n"); sleep(2); return NULL; %>./threadab %> dopsys 33
int threada(void) pthread_t threadb; int i; pthread_create(&threadb,null, threadb,null); for (i=0; i<10; i++) printf("\n"); sleep(1); pthread_join(threadb,null); return 0; int main(int argc,char *argv[]) threada(); return 0; [Click] void* threadb (void *arg) int i; for (i=0; i<10; i++) printf("\n"); sleep(2); return NULL; Vil det ikke gå galt, fordi stdout er en delt resurse? %>./threadab %> dopsys 33
int threada(void) pthread_t threadb; int i; pthread_create(&threadb,null, threadb,null); for (i=0; i<10; i++) printf("\n"); sleep(1); pthread_join(threadb,null); return 0; int main(int argc,char *argv[]) threada(); return 0; [Click] void* threadb (void *arg) int i; for (i=0; i<10; i++) printf("\n"); sleep(2); return NULL; Vil det ikke gå galt, fordi stdout er en delt resurse? %>./threadab %> A. Jo, det går galt (tænk over hvordan) B. Nej, det går godt: Operativsystemet beskytter stdout C. Nej, det går godt: Der er ikke tale om samtidighed D. stdout er slet ikke en delt resurse, fordi hver proces har sin egen kopi dopsys 33
Implementation af tråde.. kan implementeres i user space eller kernel space: User space implementation: Implementeres af runtime system i programmet. Transparent for operativsystemet. Blokerende systemkald skal håndteres. Kernel space implementation: Operativsystemet implementerer trådbegreb via systemkald. Schedulering af tråde sker i operativsystemet. Blokerende systemkald ikke noget problem. dopsys 34
spørgsmål om tråde? dopsys 35
Opsummering Koordinering: Monitor Condition variable Proces-implementation: Process Control Block Proces-tilstande Proces-operationer (Create, Suspend, Activate, Destroy) Tråde: Begreb, justering af PCB, implementation, eksempel dopsys 36