# SO Lista 1
### Zadanie 1 <!-- Gut -->

<b>Relacja rodzic-dziecko -></b> każdy proces (oprócz init i kthread) ma swojego rodzica tzn. jest jego subprocesem
<b>Identyfikator procesu (PID) -></b> unikatowy numer przypisany do procesu
<b>Identyfikator grupy procesów (PGID) -></b> unikatowy numer przypisany do grupy procesów, pomaga w zorganizowaniu drzewa procesów, sygnałów i komunikatów między nimi
<b>Identyfikator rodzica (PPID) -></b> PID rodzica
<b>Właściciel (User)-></b> kinda obvious
<b>Kto jest rodzicem init?</b>
Nikt (jego ojciec poszedł po mleko), jest to pierwszy proces jaki robi system
<b>Wątki jądra -></b> operuje w kernelspace, są tworzone przez inne uprzywilejowane wątki
<b>Wksaż wątki jądra w "ps" </b>
Wszystkie dzieci kthread
<b>Jakie jest znaczenie poszczególnych znaków w kolumnie STAT?</b>

<b>Które są wątkami?</b>
Te w {}


### Zadanie 2 (początek wyżej) <!-- Gut -->

<b>Proces zombie -></b> proces zwolniony który dalej bierze zasoby systemu
<b>Proces sierota -></b> proces którego rodzic skończył, ale ten proces mimo tego nadal działa.
<b>Jak jądro reaguje na sytuację z sierotą?</b>
Wtedy 'sierota' zostaje przygarnięta przez <b>init</b> lub najsilniejszy subproces
<b>W jaki sposób pogrzebać proces który wszedł w stan zombie?</b>
Albo parent musi wywołać wait()|waitpid() lub musi sam zterminować i wtedy init pogrzebie zombie
<b>Czemu proces nie może sam siebie pogrzebać?</b>
Bo nie może użyć wait() na sobie, poza tym exit() nie sprząta swojego stosu jądra, więc proces dalej zajmuje miejsce w pamięci
<b>Co złego mogłoby się stać, gdy:</b>
<li>Dziecko może czekać na zmianę stanu swojego
rodzica </li>
<ol>
<li>infinity loop (przez 2 waity)</li>
<li>mogą zajmować zasoby przez czekanie na init</li>
</ol>
<li>wiele procesów oczekuje na zmianę stanu jednego procesu</li>
<ol>
<li>infloop gdy dziecko czeka na wait rodzica rodzica</li>
<li>moglibyśmy zmienić execution flow programu</li>
</ol>

### Zadanie 3 <!-- Gut -->

<b>Do czego służy system plików proc(5) w systemie Linux?</b>
<li>Jest interfejsem dla struktur jądra</li>
<li>Jądro może zmieniać parametry procesu i zczytywać je</li>
<li>Zawiera katalog dla kolejnego procesu na systemie</li>


### Zadanie 4 <!-- Gut -->

XORG 608?
Adres wirtualny | rozmiar KB | uprawnienia | nazwa zmapowanego obiektu

<b>[anon] -></b> pamięć anonimowa (requestowana przez proces)
<b>segmenty programu -></b> definiowane w elfie, zawierajace 1 lub więcej ładowalnych sekcji programu, mają swoje atrybuty i z reguły są ciągłe
<b>pliki odwzorowane w pamięć -></b> segment w pamięci który ma bezpośrednie mapowanie w nazej pamięci (bajt do bajta)

### Zadanie 5 <!-- Gut -->

<b>Zasoby plikopodobne -></b> zasób mający deskryptor pliku, ale nie będący zwykłym plikiem (np. socket sieciowy)
<b>Co znaczą dane kolumny?</b>

<b>Command -></b>oryginalna komenda związana z procesem
<b>TID -></b> thread id
<b>FD -></b> nr deskryptora pliku lub

<b>Device -></b> numery urządzenia oddzielone przecinliem dla katalogów, zwykłych plików lub plikó NFS (Network File System)
<b>Size/off -></b> rozmiar pliku lub jego offset wbajtach
<b>Node -></b> numer węzła lokalnego pliku zdefinowany w globalnej strukturze
<b>Name -></b> nazwa punktu podłączenia i systemów plików w którym się znajduje
<b>Pliki zwykłe REG-></b>?
<b>Katalogi DIR-></b>?
<b>Plik urządzenia CHR/BLK-></b> Specjalny plik służący do komunikacji programu z urządzeniem poprzez używanie jego sterowników (np. plik klawiatury)
<b>Gniazdo unix (socket)-></b>pseudoplik służący do komunikacji sieciowej. Składa się z "2 końców", czyli urządzenia wysyłającego i otrzymującego dane, każdy socket musi mieć zdefiniowane:
<li>jakim typem połączenia się posługuje (TCP/UDP</li>
<li>domena w jakiej działa (rodzina protokołów jaką będzie się posługiwał)</li>
<b>Potok (pipe) FIFO -></b> mechanizm komunikacji międzyprocesowej. Najczęściej łączy się stdin programu A z stdout B.



### Zadanie 6 <!-- Gut -->

<b>Real -></b> czas od początku do końca życia procesu
<b>User -></b> czas jaki proces potrzebował na wykonanie kodu w userspace (tylko kiedy był aktywny)
<b>Sys -></b> czas jaki proces potrzebował na wykonanie kodu po stronie kernela. Czas jaki przeznaczył na wykonanie syscalli. Liczy się tylko czas konkretnego procesu
<b>Czemu suma czasów nie jest równa?</b>
Ponieważ jeśli np. proces czeka na I/O
<b>Czemu może być większy?</b>
Bo wielowątkowość xD
ulimit -t 2 && find /
<b>Jaki sygnał wysłano?</b>
Sigkill

### Zadanie 7

```c
static void do_read(int fd) {
/* TODO: Spawn a child. Read from the file descriptor in both parent and
* child. Check how file cursor value has changed in both processes. */
pid_t pid;
off_t cursor;
pid = Fork();
if(pid == 0){ /* Child */
cursor = lseek(fd,0,SEEK_CUR);
printf("File cursor position before read() @ %ld (pid:%d)\n",cursor,getpid());
if(read(fd,buf,20) != 20)
app_error("read error");
cursor = lseek(fd,0,SEEK_CUR);
printf("File cursor position after read() @ %ld (pid:%d)\n",cursor,getpid());
}
else{ /* Parent */
cursor = lseek(fd,0,SEEK_CUR);
printf("File cursor position before read() @ %ld (pid:%d)\n",cursor,getpid());
if(read(fd,buf,20) != 20)
app_error("read error");
cursor = lseek(fd,0,SEEK_CUR);
printf("File cursor position after read() @ %ld (pid:%d)\n",cursor,getpid());
}
exit(0);
}
```
```c
static void do_close(int fd) {
/* TODO: In the child close file descriptor, in the parent wait for child to
* die and check if the file descriptor is still accessible. */
pid_t pid;
int child_status;
pid = Fork();
if(pid == 0){ /* Child */
close(fd);
printf("Closed fd @ %d (pid:%d)\n",fd,getpid());
}
else{ /* Parent */
Wait(&child_status);
if(fcntl(fd,F_GETFD) == -1)
printf("Fd has been closed @ %d (pid:%d)",fd,getpid());
else
printf("Fd is still open @ %d (pid:%d)\n",fd,getpid());
}
exit(0);
}
```

### Zadanie 8 <!-- Gut -->

```c
int board[size],k = 0,selected;
/* TODO: A loop is missing here that initializes recursive algorithm. */
while (k < size && k >= 0){
selected = ndselect(size);
for(int i=0;i<k;i++)
if(conflict(k,selected,i,board[i]))
exit(0);
board[k] = selected;
k++;
}
```
```c
static int ndselect(int n) {
/* TODO: A loop is missing here that spawns processes and waits for them! */
pid_t pid;
int child_status;
for(int i=0;i<n;i++){
if((pid = Fork()) == 0)
return i;
else
Waitpid(pid,&child_status,0);
}
exit(0);
}
```
