GNU/Linux >> Linux Esercitazione >  >> Linux

Panoramica del processo UNIX (all'interno di un processo Linux e tipi di processo)

Un processo è un'istanza in esecuzione di un programma. In questo articolo abbiamo usato due termini "programma" e "istanza in esecuzione". Supponiamo di eseguire un programma contemporaneamente 5 volte, quindi in corrispondenza di ciascuna istanza ci sarà un processo in esecuzione nel sistema. Quindi diciamo che un processo è una "istanza in esecuzione" di un programma.

Come già sai, puoi usare il comando ps per visualizzare i processi in esecuzione sul tuo sistema. Per un uso efficace del comando ps, fare riferimento a 7 Esempi pratici di comandi PS per il monitoraggio del processo.

1. Sbirciando all'interno di un processo

Ora, poiché abbiamo chiaro cosa sia esattamente un processo, scaviamo un po' più a fondo per vedere in cosa consiste un processo. Un processo Unix può essere pensato come un contenitore che contiene:

Istruzioni del programma

Le istruzioni del programma sono mantenute in segmenti di testo che vengono eseguiti dalla CPU. Di solito per programmi come editor di testo che vengono eseguiti frequentemente il segmento di testo è condiviso. Questo segmento ha privilegi di sola lettura, il che significa che un programma non può modificare il suo segmento di testo.

Dati

Per lo più i dati vengono mantenuti nel segmento dati. Il segmento dati può essere classificato in segmento dati inizializzato e segmento dati non inizializzato. Come suggerisce il nome, il segmento di dati inizializzato contiene quelle variabili globali che vengono inizializzate in anticipo mentre il segmento di dati non inizializzato (noto anche come segmento "BSS") contiene variabili globali non inizializzate. Inoltre, le variabili statiche vengono memorizzate nel segmento dati.

Le variabili locali che sono locali per le funzioni sono memorizzate nello stack. Stack è particolare di una funzione e oltre a contenere le informazioni sulle variabili locali contiene anche informazioni sull'indirizzo a cui il flusso tornerà una volta terminata l'esecuzione della funzione. Stack contiene anche informazioni sull'ambiente dei chiamanti, ad esempio alcuni dei registri macchina sono anch'essi archiviati nello stack. Una funzione chiamata alloca memoria per le sue variabili locali e temporanee sullo stack stesso. In caso di funzione ricorsiva esiste uno stack indipendente per ogni chiamata di funzione.

Quindi ci sono i dati che vengono archiviati nell'heap. Questa memoria per questi dati viene allocata in fase di esecuzione sul segmento dell'heap. Il segmento dell'heap non è locale per un processo ma è condiviso tra processi. Questo è il motivo per cui i programmatori C si preoccupano molto delle perdite di memoria causate dal segmento dell'heap e che possono influire su altri processi del sistema.

Argomenti della riga di comando e variabili di ambiente

Un processo contiene anche spazio per memorizzare le variabili di ambiente e gli argomenti della riga di comando che passiamo al programma. Di solito il vettore contenente le informazioni della riga di comando viene memorizzato qui e quindi l'indirizzo di questo vettore di informazioni e il numero di elementi nel vettore viene copiato in 'argv' e 'argc' (i due argomenti nella funzione 'main()').

Oltre alle informazioni di cui sopra, un processo contiene anche informazioni come

  • Stato del suo I/O
  • La sua priorità e altre informazioni di controllo

Una delle informazioni di controllo più importanti per un processo sono i privilegi. Un processo eredita direttamente tutti i privilegi dell'utente che ha attivato questo processo. Ad esempio, un processo attivato da un utente che non dispone dei privilegi di superutente non può eseguire operazioni che richiedono privilegi di root mentre un processo attivato da root può fare qualsiasi cosa per cui è programmato. Un'eccezione alla regola di cui sopra è dove un processo può acquisire privilegi maggiori rispetto all'utente che lo ha attivato se il bit setuid o setgid è impostato per quel particolare processo. Ma non entreremo nei dettagli in merito qui (fare riferimento alle pagine man di setuid e setgid per ulteriori informazioni al riguardo).

2. Processi in background e in primo piano

Come abbiamo già discusso, possiamo avviare un processo con il suo nome in Unix. Come alcuni programmi standard, "ls", "ps" ecc. possono essere avviati semplicemente digitando il loro nome sul prompt della shell. Ci sono due modi in cui possiamo avviare un processo

  • A partire in primo piano
  • A partire in background

Supponiamo che ci sia un'utilità che consuma del tempo e fa un conteggio. Diciamo che il nome dell'utilità è 'count' Ora per attivare ed eseguire il programma in primo piano, eseguo il seguente comando (dove 'count' è il nome del binario dal codice sopra):

$ ./count
Counting done

Quindi vediamo che, dopo aver eseguito il binario './count', ci sono voluti quasi 10 secondi prima che l'output fosse visualizzato su stdout e fino ad allora la shell era occupata solo da questo processo. cioè non è possibile eseguire altre operazioni sulla stessa shell. Ora, per attivare un processo in background, aggiungi "&" alla fine del comando:

$ ./count &
[1] 4120

$ # Do some work on shell while the above program is working in the background

$ Counting done

Il segno "&" e commerciale indica che questo processo deve essere eseguito come processo in background. Eseguendo un processo in background, possiamo avere accesso alla shell per eseguire ulteriori operazioni. Come, nell'output sopra, dopo aver eseguito il "count" binario in background, ho usato un paio di altri comandi sulla stessa shell e quando il "count" binario è stato terminato con la sua elaborazione, l'output è stato ributtato sulla stessa shell (l'ultima riga). Quindi possiamo concludere che per impostazione predefinita ogni processo viene eseguito in primo piano, riceve l'input (se presente) dalla tastiera e restituisce l'output all'utente. Sebbene un processo in background venga disconnesso dalla tastiera e l'utente può utilizzare la stessa shell per eseguire più operazioni.

Per ulteriori informazioni sui processi in primo piano e in background, fare riferimento a:Come gestire i lavori in background UNIX

3. Tipi di processo

Quindi vediamo che il processo è un concetto fondamentale per un sistema operativo. Quasi tutte le attività su un sistema operativo prendono la forma di un processo per fare alcune cose. Esistono diversi tipi di processi in esecuzione su un sistema, alcuni sono :

Processi secondari

Un processo creato da un altro processo durante il runtime. Di solito i processi figlio vengono creati per eseguire alcuni binari dall'interno di un processo esistente. I processi figlio vengono creati utilizzando la chiamata di sistema fork(). Normalmente i processi vengono eseguiti tramite shell/terminale. In tal caso la shell diventa il genitore e il processo eseguito diventa il processo figlio. Su Unix/Linux ogni processo ha un genitore tranne il processo init (ne parleremo più avanti).

Processi Demoniaci

Questi sono processi speciali che vengono eseguiti in background. Sono processi relativi al sistema che non hanno un terminale associato. Questi processi eseguiti eseguiranno i permessi di root e in genere forniscono servizi ai processi. Poiché sappiamo già che un processo daemon non ha un terminale collegato, bene per ottenere ciò il processo deve essere staccato dal terminale. Il modo ideale su Linux/Unix per farlo è eseguire un processo tramite il terminale e dall'interno di questo processo creare un altro processo e quindi terminare il processo padre. Poiché il genitore è terminato, ora il figlio diventerà indipendente dal terminale e verrebbe rilevato dal processo init e quindi diventerebbe un processo daemon. Un tipico esempio potrebbe essere un demone di posta che attende l'arrivo di e-mail e notifica quando viene ricevuta una posta.

Processi orfani

Di solito un processo crea un processo figlio (come descritto sopra) e quando il processo figlio termina, viene inviato un segnale al genitore in modo che il genitore possa fare tutte le cose che è necessario fare quando uno dei figli viene terminato. Ma ci sono situazioni in cui un genitore viene ucciso. In tal caso i processi figlio diventano orfani e quindi presi in carico dal processo init. Sebbene il processo init prenda la proprietà del processo orfano, questi processi sono comunque chiamati orfani poiché i loro genitori originali non esistono più.

Processo Zombie

Quando un processo figlio viene terminato o completa la sua esecuzione, la sua voce nella tabella dei processi rimane finché il processo padre non recupera le informazioni sullo stato del figlio terminato. Quindi, fino ad allora il processo terminato entra nello stato di zombi ed è noto come processo di zombi. Quando un processo viene terminato, tutta la memoria e le risorse associate al processo vengono rilasciate ma esiste la voce del processo nella tabella dei processi. Un segnale SIGCHILD viene inviato al genitore del processo (che è appena terminato). In genere, il gestore di questo segnale nel genitore esegue una chiamata "wait" che recupera lo stato di uscita del processo terminato e quindi viene rimossa anche la voce di questo processo zombie dalla tabella del processo.

4. Il processo di inizializzazione

Come abbiamo discusso in precedenza, il processo init è la quinta fase della sesta fase del processo di avvio di Linux.

Saresti consapevole della famosa teoria del "pollo e uova" su chi è arrivato per primo. In termini di processi, poiché ogni processo ha un processo padre, la stessa domanda può essere posta sul processo padre o figlio. Bene, fortunatamente c'è una risposta qui. La risposta è il processo init che viene avviato come primo processo durante la sequenza di avvio. Ciò significa che non esiste un genitore del processo init. Verifichiamolo, poiché il PID di init è '1', utilizziamo il comando ps:

Quindi vediamo dall'output che PPID è 0, il che significa che non esiste un genitore per questo processo.

$ ps -l 1
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
4 S     0     1     0  0  80   0 -  5952 poll_s ?          0:00 /sbin/init

Di seguito sono riportati alcuni dei comandi che gestiscono i processi:comando Top, comando HTOP, comando PS, comando Kill (pkill, xkill).


Linux
  1. Comandi Linux - Panoramica ed esempi

  2. Come trovare e uccidere il processo Zombie in Linux

  3. Linux:comprensione delle autorizzazioni e dei tipi di file Unix?

  4. Processi UNIX / Linux:funzione C fork()

  5. mmap, msync e terminazione del processo linux

Storia di Unix e Linux

Linux vs Unix

Comprimere e decomprimere i comandi in Linux/Unix

Panoramica dei tipi di database distribuiti e della sicurezza

Panoramica di RAMFS e TMPFS su Linux

Come tracciare e tracciare un processo Linux