Det er ikke flere obligatoriske innleveringer, så betrakt oppgaver som er
merket (Oblig) som de oppgavene det er viktigst å få med seg i forbredelsene til eksamen.
-
Oppgave 2.11 i Tanenbaum: Hva er den største fordelen med å implementere tråder i user space(at JVM selv schedulerer og ikke OS)?
Hva er den største ulempen?
-
Lagre filen Prior.java fra forelesningen på Linux-VM og kompiler og kjør den. Hvordan behandler Linux Java Virtual Machine (JVM = /usr/lib/bin/java) prioriteringen? Endre programmet slik at tråd to endrer prioritet til 4 istedet for 1. Ser dette ut til å gi noen endring i hvordan trådene blir prioritert? Eksperimenter med forskjellige prioriteter. Ser det ut til at noen av trådene får mer prioritet? Prøv å kjøre java med
opsjonen -XX:ThreadPriorityPolicy=1 som vanlig bruker og som root med sudo java. Gir dette noen endring?
Kommenter kort det du ser. (Les http://tech.stolsvik.com/2010/01/linux-java-thread-priorities-workaround.html for mer info om dette). Bruk taskset -c 0 hvis du kjører på en maskin med flere CPUer, ellers vil ikke trådene konkurrere om CPU-tid. NB! Linux-VM er egentlig en docker-container og man har noe begrensede rettigheter i forhold til om man kjører på en Linux server eller en Linux viruell maskin. Følgende
root@os100:/home/group100# nice -n -5 ./regn
nice: cannot set niceness: Permission denied
viser at man ikke får lov til å sette negativ niceness som root som man normalt kunne gjort. Dette vil ha innvirkning på resultatet du får.
-
Gjenta det samme med filen Prior.java fra forelesningen på Windows, eventuelt en Windows-VM. Hvordan behandler Windows Java Virtual Machine (JVM = java.exe) prioriteringen sammenlignet med Linux JVM? Endre programmet slik at tråd to endrer prioritet til 4 istedet for 1. Ser dette ut til å gi noen endring i hvordan trådene blir prioritert?
- (Oblig)
I denne oppgaven skal vi ta utgangspunkt i programmet listet nedenfor.
Hvis threads eller prosesser skal jobbe mot felles data, må man generelt synkronisere
dem slik at de ikke modifiserer felles data samtidig; noe som har uforutsigbare
konsekvenser. Programmet har en felles variabel
static int saldo
som de to trådene
skal jobbe mot. Som vi har sett har Java en egen klasse Thread
og for å lage
egne threads kan du utvide denne klassen med extends
. I main()
lages nye tråder med
SaldoThread s1 = new SaldoThread();
En tråd settes i gang med s1.start().
Da startes run()
som er en metode alle threads må ha. Variabler som defineres som static
,
er felles data for alle tråder.
Studer først programmet "NosynchThread.java", som blir listet nedenfor,
ved å lese programteksten (legg merke til at main
også er
en thread):
// Kompileres med javac NosynchThread.java // Run: java NosynchThread
import java.lang.Thread;
class SaldoThread extends Thread { static int MAX = 50000000; static int count = 0; public static int saldo; // Felles variable, gir race condition int id; SaldoThread() { count++; id = count; } public void run() { System.out.println("Thread nr. "+ id +", med prioritet " + getPriority() + " starter"); updateSaldo(); } public void updateSaldo() { int i; if(id == 1) { for(i = 1;i < MAX;i++) { saldo++; } } else { for(i = 1;i < MAX;i++) { saldo--; } } System.out.println("Thread nr. " + id + " ferdig. Saldo: " + saldo); } }
class NosynchThread extends Thread { public static void main (String args[]) { int i; System.out.println("Starter to threads!");
SaldoThread s1 = new SaldoThread(); SaldoThread s2 = new SaldoThread(); s1.start(); s2.start();
try{s1.join();} catch (InterruptedException e){} try{s2.join();} catch (InterruptedException e){}
System.out.println("Endelig total saldo: " +SaldoThread.saldo); } }
|
Kompiler og kjør NosynchThread.java.
Kan du forklare hva som skjer og det merkelige sluttresultatet
for total saldo?
Hvorfor endrer sluttresultatet seg fra gang til gang når det samme programmet kjøres omigjen?
Gjør det noen forskjell på resultatet om du kjører programmet med
$ taskset -c 0 java NosynchThread
Hva endres med hvordan trådene kjøres når du kjører java med taskset på denne måten? Det kan være du må gjenta taskset-kjøringen mange ganger (eventuelt øke max-verdien i loopen) for at du skal få 'gale' resultater. Hva er forskjellen på antall mulige "kollisjoner" når trådene kjører på samme CPU sammenlignet med når de kjører på hver sin CPU?
-
Oppgave 2.19 i Tanenbaum. Hva er en race condition?
- (Oblig)
Ta utgangspunkt i programmene thread.c, minimal.s og en.c fra
forelesningen
og lagre dem på data2500. Editer først thread.c og gang antall runder i løkken med en faktor 100, til en milliard, ellers vil du ikke se den ønskede effekten på data2500. Kompiler og kjør dem først med
haugerud@data2500:~/lock$ gcc -pthread thread.c minimal.s
haugerud@data2500:~/lock$ taskset -c 0 ./a.out
Hvorfor får du nå alltid samme resultat selvom det er to uavhengige tråder som kjører?
Gjenta kjøringen ved å istedet bruke en.c på følgende måte:
haugerud@data2500:~/lock$ gcc -pthread thread.c en.c
haugerud@data2500:~/lock$ taskset -c 0 ./a.out
Kanskje må du kjøre den flere ganger for å se effekten, men hvorfor får du nå noen ganger forskjellig resultat?
Kan det ha noe å gjøre med at kompilatoren kan lage flere linjer maskinkode av en linje høynivå-kode?
Kompiler en.c på følgende måte:
haugerud@data2500:~/lock$ gcc -c -S en.c
Se så på den resulterende filen en.s og avgjør om flere linjer maskinkode kan være årsaken.
Kompiler og kjør til slutt på følgende måte:
haugerud@data2500:~/lock$ gcc -O -pthread thread.c en.c
haugerud@data2500:~/lock$ taskset -c 0 ./a.out
Hvorfor blir resultatet nå alltid det samme?
-
Ukens nøtt:
Ta utgangspunkt i C-programmet
main(){ int i,S = 0; for(i=1;i < 5;i++){ S = S + i; } }
|
kompiler det på en Linux host og finn ut hva som utgjør maskinkoden for main ved hjelp av objdump -d a.out.
Prøv å finne ut hva denne koden gjør og hvorfor den er en korrekt oversettelse av for-løkken til maskinkode.
Hvilken av høynivå variablene (i og S) tilsvarer -0x8(%rbp) og hvilken tilsvarer -0x4(%rbp)?
Hvilket tall ligger lagret i -0x8(%rbp) når løkken har kjørt ferdig?
Hint: $0x4 er tallet fire, -0x8(%rbp) er en referanse til et sted i minne der denne variabelen lagres,
-0x4(%rbp) er en annen variabel, %eax er et register, og 80483d4 er et linjenummer.
- (Oblig)
Dette var i fjor en nøtt, men i år skal du spørre Sikt-ChatGPT om hjelp, paste inn følgende spørsmål:
Ta utgangspunkt i Java-programmet
class For{ public static void main(String args[]){ int i,S = 0; for(i=1;i < 5;i++){ S = S + i; } } }
|
kompiler det på en Linux host og finn ut hva som utgjør bytekoden gjør ved hjelp av javap -c For.
Forklar hvorfor den er en korrekt oversettelse av for-løkken til bytekode.
Hvilken av høynivå variablene (i og S) tilsvarer variable 1 og hvilken tilsvarer variable 2 (lagres der med istore_2).
Hvilke tall ligger lagret i variable 1 og variable 2 når løkken har kjørt ferdig?
- a) Kompiler koden på en Linux VM og se
om du får samme bytecode som ChatGPT angir når du kjører javap -c For.
- b) Les igjennom svaret du får og vurder om dette er et korrekt svar.
- c) Hvordan kan ChatGPT presentere denne byte-koden for deg når den ikke har tilgang til en javakompilator slik
at den kan kjøre dette på en server og generere bytecode? (spør ChatGPT om du ikke vet svaret)
- (Oblig)
Gi følgende spørsmål til Sikt-ChatGPT:
Inntil 2005 var det slik at det fantes noen x86 instruksjoner (som for eksempel POPF) som bare ble oversett om de ble utført i user mode. Det disse instruksjonene utførte skulle bare være lov å gjøre i kernel mode og ingen ting skjedde når de ble utført i user mode. Forklar kort hva som gjorde dette problematisk i forbindelse med virtualisering
og hvordan disse hardware-instruksjonene ble endret for å støtte x86-virtualisering.
Sammenlign svaret med det som står skrevet om dette i forelesningsnotaten og vurder om du har fått et korrekt svar fra ChatGPT.
- (Oblig)
På gruppens os-server, installer PowerShell for Linux med følgende kommandoer:
# wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb"
# dpkg -i packages-microsoft-prod.deb
# apt-get update
# apt-get install -y powershell
Da vil du på os-serveren ved å kjøre kommandoen pwsh få opp nøyaktig samme PowerShell som vil bli tilgjengelig under eksamen:
group131@os131:~$ pwsh
PowerShell 7.5.0
PS /home/group131>
PS /home/group131> Get-ChildItem
Directory: /home/group131
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
drwxrwxr-x group131 group131 04/17/2023 14:56 4096 j
-rwx------ group131 group131 03/26/2023 22:38 33 a.sh
Du kan gjøre de fleste av de kommende PowerShell-oppgavene med dette shellet og det kan være praktisk å kjenne til
dette shellet da det pleier å være noen praktiske PowerShell-oppgaver til eksamen. Legg merke til at det er noen
forskjeller fra et standard Windows PowerShell. I Windows er ls et alias for Get-ChildItem. Hva er kommandoen ls i
pwsh? (hint: bruk Get-Command).
- (Oblig)
Kjør følgende bash-script i en mappe på en Linux maskin og forklar kort hva resultatet blir:
mkdir dir
cd dir
echo hei > fil.txt
cp fil.txt lik.txt
mv fil.txt ..
cp lik.txt kopi.txt
rm lik.txt
ls
Lag et PowerShell-script som gjør det samme som bash-scriptet, kjør det i PowerShell og sjekk at resulatet blir likt. Hvilke Cmdlets og functions bruker scriptet?
- (Oblig)
Skriv ut verdien av systemvariabelen $PSVersionTable for å se
hvilken versjon av powershell du kjorer.
- (Oblig)
CreationTime er en property for et PowerShell filobjekt.
Gi en PowerShell-kommando som gir hvilket tidspunkt filen fil.txt i mappen du står i ble laget. Hvis dere
gjør oppgavene i pwsh-shellet i os-gruppen sin Linux-VM, er det viktig at man bruker de 'ekte' Cmdlet-ene som
Get-Childitem og Get-Process og ikke ls og ps, fordi de sistnevnte da vil kjøre det underliggende Linux-kommandoene ls
og ps og ikke PowerShell Cmdlet'ene.
- (Oblig)
Gi en PowerShell-kommando som gir årstallet for når filen C:\Windows\system.ini (eller /etc/passwd
i pwsh) ble laget.
-
Gi en PowerShell-kommando som gir full path til filen fil.txt i mappen du står i.
- (Oblig)
Gi en PowerShell-kommando som skriver ut prosess-IDen for prosessen med navn 'idle' (eller sshd i pswh). Bruk først Get-Member for å finne
ut hvilke properties Cmdlet'en har.
- (Oblig)
Start en notepad-prosess fra PowerShell. Bruk så en ps-metode som gjør at nodepad-prosessen stoppes . Bruk først Get-Member for å finne ut hvilke properties ps har. Lag en ny notepad-prosess og bruk aliaset kill til å drepe den. Hva skjer om du har to notepad-prosesser?
-
Følgende kommando gir størrelsen på filen "test.txt" i antall bytes:
(ls test.txt).Length
Følgende kommando gir nøyaktig samme output:
(ls test.txt).get_Length();
Forklar forskjellen på disse kommandoene.
- (Oblig)
Skriv et powershell-script som ved hjelp av en løkke skriver ut følgende:
Linje 2
Linje 4
Linje 6
Linje 8
-
Skriv en powershell oneliner som dreper alle prosesser med navn notepad.
- (Oblig)
I denne oppgaven som er relatert til plattformavhengighet skal du ta utgangspunkt i en fil som er spesiallaget kun for din
s-gruppe. Filene for alle gruppene ligger på
denne websiden. Man kan ikke liste filene på denne websiden, men for gruppe s133 ligger det der en kjørbar
fil som heter p133 på denne websiden, tilsvarende for andre s-brukere. Pass på å velge filen som er til din s-gruppe og ikke til din
os-gruppe!
Hvis den kjøres på riktig plattform, gir den en 10-tegns kode med tilfeldige tegn som viser at du har
løst oppgaven. Det er mulig å få tilgang til riktig plattform ved å laste ned riktig container til
s-serveren din. Hvis det er for mange som samtidig prøver å laste ned samme type container, kan du få en beskjed om at
det ikke går an å laste ned flere containere. (docker: Error response from daemon: toomanyrequests: You have reached
your pull rate limit) Da er det mulig å prøve å laste ned containeren du ønsker fra
public.ecr.aws/docker/library/navnet-til-containeren-du-vil-laste-ned istedet. For de utålmodige, kan det også være mulig å hacke seg
frem til en løsning uten en container med den riktige plattformen, men det er et poeng med oppgaven at man skal kunne
hente ned forskjellige platformer og kjøre dem. For å sjekke at du har funnet rette streng, skriv den inn på siden
os.php uke 15
og du får beskjed om du har skrevet riktig. I tilegg blir du da med på konkurransen om å finne denne koden fortest mulig!