Curs 2 - Managementul Proceselor și Scheduling în Sistemele de Operare

În acest curs vom explora modul în care sistemele de operare gestionează procesele, alocarea resurselor și strategiile de planificare (scheduling) utilizate pentru optimizarea performanței.

1. Ce este un Proces?

Un proces este o instanță a unui program aflat în execuție. Un proces poate avea unul sau mai multe fire de execuție (threads).

- Stările unui proces:

- New: Procesul este creat.

- Ready: Procesul este pregătit pentru execuție.

- Running: Procesul este în execuție pe CPU.

- Waiting: Procesul așteaptă un eveniment (I/O, semnal).

- Terminated: Execuția procesului s-a încheiat.

- Process Control Block (PCB): Fiecare proces are un PCB care conține informații despre starea sa, resursele utilizate și registrul de instrucțiuni.

2. Crearea și Terminarea Proceselor

Sistemele de operare oferă mecanisme pentru crearea și terminarea proceselor.

- Syscalls pentru gestionarea proceselor:

pid_t pid = fork(); // Crează un proces copil
execl("/bin/ls", "ls", NULL); // Înlocuiește procesul curent
wait(NULL); // Așteaptă terminarea unui proces copil
exit(0); // Termină execuția procesului

- Procese zombi și orfane:

- Proces Zombi: Procesul a fost terminat, dar intrarea sa din tabelul proceselor nu a fost eliminată de părinte.

- Proces Orfan: Părintele unui proces a fost terminat, iar procesul copil este adoptat de init/systemd.

3. Algoritmi de Scheduling a Proceselor

- FIFO (First Come, First Served - FCFS): Procesele sunt executate în ordinea sosirii.

- Round Robin (RR): Fiecare proces primește un quantum de timp fix.

- Shortest Job Next (SJN) și Shortest Remaining Time First (SRTF): Procesul cu timpul de execuție cel mai scurt are prioritate.

- Priority Scheduling: Fiecare proces are o prioritate, procesele cu prioritate mai mare sunt executate primele.

- Multilevel Queue Scheduling: Procesele sunt împărțite în cozi separate (ex: foreground vs. background tasks).

4. Threading și Multitasking

- Threading vs. Multiprocessing: Thread-urile partajează memoria procesului, în timp ce procesele rulează separat.

- POSIX Threads (pthreads) în Linux:

#include <pthread.h>
#include <stdio.h>
void *print_mesaj(void *arg) {
    printf("Hello from thread!\n");
    return NULL;
}
int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, print_mesaj, NULL);
    pthread_join(tid, NULL);
    return 0;
}

- Sincronizarea thread-urilor:

- Mutex: Blocare exclusivă a resurselor.

- Semafoare: Control asupra accesului mai multor fire de execuție.

- Spinlocks: Mecanism de blocare activă pentru latență redusă.

5. Exemplu Practic - Crearea și Gestionarea Proceselor

a) Listarea și monitorizarea proceselor

ps aux | grep firefox

Această comandă afișează toate procesele care rulează instanțe ale Firefox.

b) Crearea unui proces în C

#include <stdio.h>
#include <unistd.h>
int main() {
    pid_t pid = fork();
    if (pid == 0) {
        printf("Proces copil cu PID: %d\n", getpid());
    } else {
        printf("Proces părinte cu PID: %d\n", getpid());
    }
    return 0;
}

c) Implementarea unui scheduler simplu în Python

import queue
q = queue.Queue()
q.put('P1')
q.put('P2')
q.put('P3')
while not q.empty():
    proces = q.get()
    print(f'Execut {proces}')

Resurse suplimentare: