IN 147 Program og maskinvare

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

Kort notat om parallellstyring IN147

Oppsummering av IN147 siste del Operativsystemer Parallellisering Veien videre

Dagens tema: Synkronisering

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

Dagens tema: Synkronisering

IN 147 Program og maskinvare. Dagens tema:

Oversikt over IN147(A):

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

Programmeringsspråket C

Løsningsforslag til eksamen i IN 147(A)

Dagens tema C, adresser og pekere

Ark 3 av 26. printf("i adresse %08x ligger b med verdien %d.\n", &b, b); printf("i adresse %08x ligger a med verdien %d.

Del 1 En oversikt over C-programmering

Dagens tema: Enda mer MIPS maskinkode

Dagens tema: Datastrukturer

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

IN 147 Program og maskinvare

Programmeringsspråket C

INF1010 Tråder J. Marit Nybakken Motivasjon. Å lage en tråd

Stein Gjessing. Institutt for informatikk. Universitetet i Oslo. Institutt for informatikk

Programmeringsspråket C

Løsningsforslag til eksamen i IN 147(A)

Sortering med tråder - Quicksort

Avdeling for ingeniørutdanning Institutt for teknologi

Den siste dagen. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Veien videre... Eksamen

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

IN 147 Program og maskinvare

Pensum Hovedtanker Selvmodifiserende Overflyt Veien videre Eksamen. Oppsummering

IN 147 Program og maskinvare

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

IN 147 Program og maskinvare

Del 4 Noen spesielle C-elementer

UNIVERSITETET I OSLO

Dagens tema: Parallellstyring

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

GUI («Graphical User Interface») del 2

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

Tråder Repetisjon. 9. og 13. mai Tråder

Dagens tema. Mer om C Enkle datatyper Sammensatte datatyper: Vektorer og matriser Tekster Mengder Strukturer Unioner Ringbuffere

Eksamen INF1010 V2009 Del B prøveeksamen V2010 Vekt 60 %

Tråder Repetisjon. 9. og 13. mai Tråder

Synkronisering II. Kapittel 7. Betingelse oppfylt (0) liste. tråd-deskriptor. venteliste. tråd-deskriptor. tråd-deskriptor.

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

I et Java-program må programmøren lage og starte hver tråd som programmet bruker. Er dette korrekt? Velg ett alternativ

Dagens tema INF1070. Vektorer (array er) Tekster (string er) Adresser og pekere. Dynamisk allokering

UNIVERSITETET I OSLO

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

IN 147 Program og maskinvare

La oss begynne med en repetisjon av hva som skjer når du kjører Javaprogrammet

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

UNIVERSITETET I OSLO

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

INF 1010, vår 2005 Løsningsforslag uke 11

Forelesning inf Java 5

Oppgave 1 Oversettelse (vekt 16%)

Forelesning inf Java 5

Programmeringsspråket C Del 3

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

UNIVERSITETET I OSLO

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

En oppsummering (og litt som står igjen)

Kapittel 1 En oversikt over C-språket

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

Dagens tema INF1070. Makroer. Sanntidsprogrammering. Avbrudd. Bruker- og supermodus. Blanding av C og assemblerkode. Selvmodifiserende kode

IN 147 Program og maskinvare. Dagens tema

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

Vektorer. Dagens tema. Deklarasjon. Bruk

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

INF Uke 10. Ukesoppgaver oktober 2012

INF2100. Oppgaver 23. og 24. september 2010

UNIVERSITETET I OSLO

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Rekursjon. (Big Java kapittel 13) Fra Urban dictionary: recursion see recursion. IN1010 uke 8 våren Dag Langmyhr

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

Forslag til løsning på oppgavesett for uke 40

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

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

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

Rekursjon. (Big Java kapittel 13) Fra Urban dictionary: recursion see recursion. IN1010 uke 8 våren Dag Langmyhr

Dagens tema. Makroer Ofte gjentar man kodelinjer når man skriver assemblerkode. Da kan det lønne seg å definere en makro:

Hvordan en prosessor arbeider, del 1

Fra Python til Java, del 2

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Programmeringsspråket C Del 2

INF1000: noen avsluttende ord

INF Notater. Veronika Heimsbakk 10. juni 2012

Programmeringsspråket C Del 2

Programmeringsspråket C Del 2

Transkript:

Dagens tema: Lettvektsprosesser Moderne synkroniseringsmetoder Meldinger Monitorer Programkode er også bit-mønstre! Selvmodifiserende kode Ark 1 av 23 Forelesning 7.5.2001

Lettvektsprosesser Det er vanlig å tegne en prosess slik: Stakk Data Kode En lettvektsprosess (ofte kalt «tråd») deler data- og kodelager med opphavet: Stakk Stakk Data Kode Dataoverføring er da ikke lenger noe problem, men synkronisering er stadig nødvendig. Forelesning 7.5.2001 Ark 2 av 23

Lettvektsprosesser i Java I Java kan man opprette lettvektsprosesser ved å deklarere subklasser av Thread som inneholder en metode run: class PingPong extends Thread { String id; int ventetid; PingPong(String idx, int ventx) { id = idx; ventetid = ventx; public void run() { try { while (true) { System.out.print(id + " "); sleep(ventetid); catch (Exception e) { return; public static void main(string args[]) { new PingPong("ping", 33).start(); new PingPong("PONG", 84).start(); Metoden start() brukes til å starte tråden, og stop() til å stoppe den. maskin navn> java PingPong ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping PONG ping ping Forelesning 7.5.2001 Ark 3 av 23

Parallellstyring på høyt nivå Teknikkene beskrevet hittil har vært mellomnivåteknikker; de fungerer fint hvis programmeren behersker dem tilstrekkelig godt og ikke gjør feil. Feil bruk av semaforer semaphore mutex = 1; semaphore empty = N; /* Teller tomme */ semaphore full = 0; /* Teller fulle */ void producer() { int item; while (TRUE) { produce_item(&item); down(&mutex); down(&empty); /* Byttet! */ enter_item(item); up(&mutex); up(&full); void consumer() { int item; while (TRUE) { down(&full); down(&mutex); remove_item(&item); up(&mutex); up(&empty); consume_item(item); Forelesning 7.5.2001 Ark 4 av 23

Her kan følgende skje: 1. Vi antar at produsenten har vært raskere enn konsumenten slik at bufferen nå er full. 2. Produsenten lager enda ett element. Så utfører den down(&mutex) og går inn i kritisk region, og deretter down(&empty). Nå blokkeres den fordi bufferen er full. 3. Så skjer et prosessbytte. 4. Konsumenten gjør en down(&full) og deretter en down(&mutex) for å gå inn i kritisk region. Da blokkeres den, fordi produsenten allerede er i kritisk region. Vi har altså fått en situasjon med vranglås fordi to kall på down ble byttet om. Vi ønsker oss mer høynivå mekanismer hvor deterlettereåunngåslikt. Forelesning 7.5.2001 Ark 5 av 23

Meldinger Mange parallelle systemer er basert på en mekanisme som kalles meldinger. Det finnes mange varianter; én ser slik ut: Oversikt over meldinger Det finnes kun to operatorer for meldinger: send(q, kode, data ) sender meldingen data til meldingskøen q. Senderen blokkeren hvis køen er full, ellers ikke. receive(q, kode, & data ) henter en melding med angitt kode fra køen q. Henteren blokkeres inntil det finnes meldinger i køen. Forelesning 7.5.2001 Ark 6 av 23

Bruk av UNIX-meldinger #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> typedef struct { long id; char data[200]; mess_struct; void barn(int n, int q) { mess_struct m; int r_stat; printf("dette er barn nr %d\n", n); r_stat = msgrcv(q, &m, sizeof(m), n, 0); printf("barn %d: status=%d, id=%d, data=\"%s\"\n", n, r_stat, m.id, m.data); Meldingene er av typen mess struct; legg merke til at koden (id) ligger i første ord. Barne henter en melding med riktig kode (n) fra køen q (med msgrcv) og skriver ut data de får. maskin navn> q Dette er barn nr 1 Dette er barn nr 2 Barn 2: status=204, id=2, data="dette er post 2." Barn 1: status=204, id=1, data="dette er post 1." Forelesning 7.5.2001 Ark 7 av 23

int main(void) { mess_struct m1, m2; int q, status; q = msgget(ipc_private, 0700); /* Opprett køen */ if (q < 0) { perror("q"); exit(1); if (safefork() == 0) { barn(1,q); exit(0); if (safefork() == 0) { barn(2,q); exit(0); m1.id = 1; strcpy(m1.data, "Dette er post 1."); m2.id = 2; strcpy(m2.data, "Dette er post 2."); if (msgsnd(q,&m2,sizeof(m2),0)<0) { perror("q"); exit(12); if (msgsnd(q,&m1,sizeof(m1),0)<0) { perror("q"); exit(11); wait(&status); wait(&status); /* Vent på barna */ msgctl(q, IPC_RMID, NULL); /* Fjern køen */ Hovedprogrammet gjør følgende: 1. oppretter en meldingeskø q, 2. oppretter to barneprosesser, 3. bygger opp to meldinger m1 og m2, 4. sender de to meldingene til køen q, 5. venter til barna dør og 6. fjerner køen q. Forelesning 7.5.2001 Ark 8 av 23

Vurdering + Meldinger er enkle å bruke og forstå. + De er enkle å implementere. Resultatet er at meldinger brukes svært mye. Forelesning 7.5.2001 Ark 9 av 23

Monitorer Den aller første høynivåløsningen ble oppfunnetavc.a.r.hoareogper Brinch-Hansen i 1974. Den består av en klasse-lignende struktur kalt en monitor: class Eksempel { int i; // Lokal variabel. void synchronized p(...) {. wait();. notify();. // Operator: Eksempel e; e :- new Eksempel(); e.p(...); Forelesning 7.5.2001 Ark 10 av 23

Følgende gjelder for monitorer: Kun én prosess av gangen får utføre en operator i en monitor. Ytterligere forsøk på kall vil bli blokkert inntil monitoren er ledig. (I Java angis dette med synchronized.) Alle de lokale variablene er usynlige utenfor monitoren. (Dette kreves ikke i Java, men jeg anbefaler det.) En monitor kan blokkere seg selv ved å benytte wait() vil blokkere prosessen. Monitoren vil da bli åpnet for andre prosesser. notify() vil starte en eller annen prosess som tidligere ble blokkert ved å utføre wait(). Forelesning 7.5.2001 Ark 11 av 23

PK-problemet med Javas monitorer Produsenten class Producer extends Thread { Monitor m; intx,i,s,n; Producer(int start, int inkr, int sleep, Monitor mx) { x = start; i = inkr; s = sleep; m = mx; n = 0; public void run() { while (n < 20) { m.enter(x); x += i; ++n; try { sleep(s); catch (Exception e) { return; Produsenten er en lettvektsprosess som genererer 20 tall x, x + i, x + 2i,...,x+19i som sendes til monitoren med m.enter(x). Etter hvert tall sover prosessen litt. Forelesning 7.5.2001 Ark 12 av 23

Konsumenten class Consumer extends Thread { Monitor m; Consumer(Monitor mx) { m = mx; setdaemon(true); public void run() { int n_on_line = 0; while (true) { int x = m.remove(); System.out.print(x + " "); if (++n_on_line%10 == 0) System.out.println(""); Konsumenten er en lettvektsprosess som henter tall fra monitoren med m.remove() og skriver dem ut, 10 på hver linje. Konsumenten er konfigurert som demon slik at den automatisk drepes når alle brukerprosessene er ferdige. Forelesning 7.5.2001 Ark 13 av 23

Monitoren (med hovedprogrammet) class Monitor { // En ringbuffer: private int buf[], inn_p = 0, ut_p = 0, n = 0; Monitor() { buf = new int[10]; public synchronized void enter(int x) { try { while (n == 10) wait(); catch (Exception e) { System.exit(1); buf[inn_p++] = x; ++n; if (inn_p >= 10) inn_p = 0; notify(); public synchronized int remove() { int res; try { while (n == 0) wait(); catch (Exception e) { System.exit(2); res = buf[ut_p++]; --n; if (ut_p >= 10) ut_p = 0; notify(); return res; public static void main(string args[]) { Monitor m = new Monitor(); new Producer(1,2,25,m).start(); new Producer(101,1,40,m).start(); new Consumer(m).start(); Forelesning 7.5.2001 Ark 14 av 23

Hoveprogrammet Hovedprogrammet main oppretter en monitor. Så oppretter den to produsenter og én konsument som startes. Monitoren Monitoren har en privat ringbuffer til bufring av 10 tall. Den har to operatorer: enter venter først til det er plass i ringbufferen. Så setter den inn et element og kaller notify (i tilfelle en konsument venter). remove venter først til det er noen elementer i ringbufferen. Så henter den ett element derfra som skal returneres. Først kaller den imidlertid notify (i tilfelle noen produsenter venter). Siden ringbufferen er private og operatorene er synchronized, er parallellstyringen sikker. Kjøring Slik blir en kjøring: maskin navn> java Monitor 1 101 3 102 5 103 7 9 104 11 105 13 15 106 17 107 19 21 108 23 109 25 27 110 29 111 31 33 112 35 113 37 39 114 115 116 117 118 119 120 Forelesning 7.5.2001 Ark 15 av 23

Vurdering + Monitorer er meget sikre. Kompilatoren vil ta seg av det meste av parallellitetskontrollen. + De er enkle å bruke. Det er lettere å unngå vranglås. + Det er trivielt å overføre data mellom prosessene (ved å benytte parametre til monitor-operatorene). + De gir anledning til strukturert programmering, siden monitorer er en form for abstrakte typer. Monitorer krever et eget språk; det er ikke nok å skrive noen rutiner. Svært få språk har monitorer. Konklusjon Monitorer er ypperlige, hvis de finnes. Forelesning 7.5.2001 Ark 16 av 23

Oppsummering av teknikker Teknikk Synk Data Spesielt UNIX filer UNIX rør Forutsetter samme urprosess Delt lager Lettvektsprosesser Semaforer Meldinger Monitorer Lite brukt Forelesning 7.5.2001 Ark 17 av 23

Programkode Som omtrent alt annet i en datamaskin er programkode representert med bit-mønstre. Anta at vi skriver funksjonen #include <regdef.h>.text.globl sumn # Navn: sumn. # Synopsis: Beregner summen 1+2+...+n # med formelen n*(n+1)/2. # C-signatur: unsigned sumn(unsigned n). sumn: addi t0,a0,1 # (n+1) multu t0,a0 # n* mflo v0 # sra v0,v0,1 # /2; jr ra # return Denne funksjonen beregner summen av de n første tallene ved å benytte formelen n k=1 k = n(n + 1) 2 Forelesning 7.5.2001 Ark 18 av 23

Assemblering Programmet oversettes («assembleres») til maskinkode med cc: maskin navn> cc -c sumn.s Disassemblering Programmet dis går den motsatte veien: maskin navn> dis sumn.o **** DISASSEMBLER **** disassembly for sumn.o section.text 0x 0: 20 88 00 01 addi t0,a0,1 0x 4: 01 04 00 19 multu t0,a0 0x 8: 00 00 10 12 mflo v0 0x c: 00 02 10 43 sra v0,v0,1 0x 10: 03 e0 00 08 jr ra 0x 14: 00 00 00 00 nop 0x 18: 00 00 00 00 nop 0x 1c: 00 00 00 00 nop Forelesning 7.5.2001 Ark 19 av 23

Bit-mønstre som kode Vi kan også legge inn bit-mønstrene i en vektor: #include <stdio.h> unsigned long code[] = { 0x20880001, 0x01040019, 0x00001012, 0x00021043, 0x03e00008, 0, 0, 0; int main(void) { unsigned (*f)(unsigned) = (unsigned(*)(unsigned))code; int i; for (i = 1; i <= 6; ++i) printf("f(%d) = %u\n", i, f(i)); return 0; Ved å «lure» C til å tro at adressen til vektoren code er adressen til funksjonen f, kan vi kalle f. maskin navn> cc sumn.c -o sumn && sumn f(1) = 1 f(2) = 3 f(3) = 6 f(4) = 10 f(5) = 15 f(6) = 21 Forelesning 7.5.2001 Ark 20 av 23

Selvmodifiserende kode Siden programkoden bare er bit-mønstre, kan vi da endre koden under kjøring? #include <stdio.h> /* Funksjon som returnerer 1, 2, 3,... */ unsigned long code[] = { 0x20020001, /* addi v0,zero,1 */ 0x03e00008, /* jr ra */ 0, /* nop */ 0, /* nop */ 0 /* nop */ ; #define CACHE_SIZE 16384 void clear_cache(void) { int a[cache_size], i; for (i=cache_size/sizeof(int); i>=0; --i) ++a[i]; int main(void) { int (*f)(void) = (int(*)(void))code; int i; for (i = 1; i <= 6; ++i) { printf("f() = %d\n", f()); ++code[0]; clear_cache(); return 0; Forelesning 7.5.2001 Ark 21 av 23

På noen maskiner vil dette gå bra: maskin navn> cc newn.c -o newn && newn f(1) = 1 f(2) = 2 f(3) = 3 f(4) = 4 f(5) = 5 f(6) = 6 Det er to grunner til at dette ikke alltid går: Kode og data kan ligge i ulike deler av lageret, og kodelageret er ofte skrivebeskyttet. Kode- og datalageret har ofte separat cache, så endring i det ene vil da ikke merkes i det andre. (I eksemplet løses dette problemet av funksjonen clear cache.) Selvmodifiserende kode brukes nesten aldri. + Slik kode kan øke hastigheten siden man slipper noen tester. Det er nesten umulig å finne feil i slik kode. Forelesning 7.5.2001 Ark 22 av 23

Problem med gets Funksjonskallet char linje[80]; int a, b, c;. gets(linje); leser neste linje fra standard inn (som vanligvis er tastaturet) og legger den i linje. Hva hvis linjen er for lang? Da skriver den over a, b og c og andre variable. Hva hvis linjen er flere tusen tegn lang? Da kan den skrive over programkoden. Hvis brukeren kjenner programkoden, kan altså han eller hun endre den etter ønske! Dette har vært benyttet i flere innbrudd, blant annet Morris-ormen, som er beskrevet på notatet fra i fjor om sikkerhet og virus (http://www.ifi.uio.no/in147/forelesninger/sikkerhet.pdf). Forelesning 7.5.2001 Ark 23 av 23