College Online
0%

Conceito de Processo

Modulo 2 · Aula 1 ~18 min de leitura Nivel: Fundamental

Video da aula estara disponivel em breve

Programa vs. Processo

A distincao entre programa e processo e fundamental e frequentemente cobrada em provas:

Um mesmo programa pode ter varios processos simultaneos. Por exemplo, voce pode abrir tres terminais executando bash — sao tres processos distintos do mesmo programa.

i
Analogia Um programa e como uma receita de bolo escrita num livro. Um processo e o ato de preparar o bolo seguindo a receita: envolve ingredientes (dados), o cozinheiro (CPU), o espaco na cozinha (memoria), e o estado atual (em qual passo da receita estamos).

Estrutura de um Processo

Cada processo em execucao possui um espaco de enderecamento virtual que tipicamente contem:

Layout de Memoria
Enderecos altos
+---------------------------+
|         Stack             |  ← variaveis locais, enderecos de retorno
|          ...              |     cresce para baixo
|                           |
|                           |
|          ...              |
|         Heap              |  ← alocacao dinamica (malloc/new)
|                           |     cresce para cima
+---------------------------+
|         BSS               |  ← variaveis globais nao inicializadas
+---------------------------+
|         Data              |  ← variaveis globais inicializadas
+---------------------------+
|         Text (Code)       |  ← instrucoes do programa (read-only)
+---------------------------+
Enderecos baixos

Process Control Block (PCB)

O kernel mantem uma estrutura de dados para cada processo chamada PCB (Process Control Block), tambem chamada de task_struct no Linux. Essa estrutura armazena todas as informacoes que o SO precisa para gerenciar o processo:

C (simplificado)
// Versao simplificada de como um PCB pode ser representado
struct pcb {
    int           pid;           // Process ID
    int           state;         // RUNNING, READY, WAITING...
    int           priority;      // prioridade de escalonamento
    unsigned long pc;            // program counter
    unsigned long registers[16]; // registradores salvos
    unsigned long stack_ptr;     // ponteiro de pilha
    struct mm_struct *memory;    // info de memoria
    struct file    *open_files;   // arquivos abertos
    unsigned long cpu_time;      // tempo de CPU usado
};

Criacao de Processos

Em sistemas Unix/Linux, processos sao criados pela system call fork(). O fork() cria uma copia quase identica do processo que o chamou (o pai), produzindo um novo processo (o filho).

C
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    printf("Processo pai: PID = %d\n", getpid());

    pid_t pid = fork();

    if (pid < 0) {
        // Erro: fork falhou
        perror("fork");
        return 1;
    }

    if (pid == 0) {
        // Este codigo roda no processo FILHO
        printf("Filho: PID = %d, pai = %d\n", getpid(), getppid());
        // Tipicamente, o filho chama exec() para rodar outro programa
        execlp("ls", "ls", "-la", NULL);
    } else {
        // Este codigo roda no processo PAI
        printf("Pai: esperando filho %d terminar...\n", pid);
        wait(NULL);  // espera o filho terminar
        printf("Pai: filho terminou.\n");
    }

    return 0;
}
*
Experimente Compile o codigo acima com gcc -o fork_demo fork_demo.c e execute. Observe os PIDs impressos. Execute varias vezes — os PIDs mudam a cada execucao.

Hierarquia de Processos

No Linux, todo processo (exceto o primeiro, o init ou systemd com PID 1) tem um processo pai. Isso cria uma arvore de processos que voce pode visualizar com o comando pstree:

Shell
# Ver a arvore de processos
$ pstree -p

systemd(1)─┬─sshd(1234)───sshd(5678)───bash(5679)───vim(5680)
            ├─nginx(2345)─┬─nginx(2346)
            │             └─nginx(2347)
            └─postgres(3456)─┬─postgres(3457)
                             └─postgres(3458)

# Ver informacoes de um processo especifico
$ ps aux | grep nginx

# Ver o /proc filesystem (interface do kernel para processos)
$ ls /proc/1/
$ cat /proc/self/status  # info do processo atual

Terminacao de Processos

Um processo pode terminar de varias formas:

Quando um processo termina, o SO libera todos os seus recursos: memoria, arquivos abertos, locks. O processo pai pode obter o codigo de saida do filho atraves de wait().

!
Processos zumbi e orfaos Se um pai nao chama wait(), o filho terminado fica como zumbi (zombie) — o PCB permanece na tabela de processos. Se o pai termina antes do filho, o filho fica orfao e e adotado pelo init/systemd (PID 1).

Resumo

Verifique seu entendimento

Apos uma chamada fork() bem-sucedida, quantos processos existem e o que cada um recebe como retorno?

  • Um processo; o fork retorna o PID do novo processo
  • Dois processos; ambos recebem 0 como retorno
  • Dois processos; o pai recebe o PID do filho e o filho recebe 0
  • Dois processos; o pai recebe 0 e o filho recebe o PID do pai