---
# System prepended metadata

title: SO Lista 1

---

# SO Lista 1

### Zadanie 1 <!-- Gut -->
![](https://i.imgur.com/oG6GD4t.png)

<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>
![](https://i.imgur.com/rtT8kd6.png)

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

![](https://i.imgur.com/AJ1nd4n.jpg)
![](https://i.imgur.com/18JRmAv.jpg)

### Zadanie 2 (początek wyżej) <!-- Gut -->
![](https://i.imgur.com/xtoCUUx.png)
<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>

![](https://i.imgur.com/ZHQ14SC.jpg)


### Zadanie 3 <!-- Gut -->
![](https://i.imgur.com/VhMMaV6.png)

<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>

![](https://i.imgur.com/Y64doHN.png)

![](https://i.imgur.com/FAISHTJ.jpg)



### Zadanie 4 <!-- Gut -->
![](https://i.imgur.com/KW6aXom.png)
XORG 608?

Adres wirtualny | rozmiar KB | uprawnienia | nazwa zmapowanego obiektu 
![](https://i.imgur.com/DXN3IJK.png)

<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)

![](https://i.imgur.com/UHxQCRR.jpg)




### Zadanie 5 <!-- Gut -->
![](https://i.imgur.com/Wg79RvY.png)

<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>
![](https://i.imgur.com/0LUxelf.png)
<b>Command -></b>oryginalna komenda związana z procesem 
<b>TID -></b> thread id
<b>FD -></b> nr deskryptora pliku lub
![](https://i.imgur.com/d0d9oWO.png)
<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.





![](https://i.imgur.com/NlMLA22.jpg)

![](https://i.imgur.com/xj6glvF.jpg)

![](https://i.imgur.com/NrglHWj.jpg)



### Zadanie 6 <!-- Gut -->
![](https://i.imgur.com/f4hBDY2.png)
<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
![](https://i.imgur.com/4AeCgs7.jpg)

### Zadanie 7
![](https://i.imgur.com/jB373UZ.png)

```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);
}
```
![](https://i.imgur.com/RL03N92.jpg)


### Zadanie 8 <!-- Gut -->
![](https://i.imgur.com/GhKplyc.png)

```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);
}
```
![](https://i.imgur.com/QqVdoh5.jpg)

