I demoni sono processi che non vengono eseguiti direttamente sotto il controllo dell'utente ma servono in background. Di solito, si avviano all'avvio del sistema e funzionano continuamente fino allo spegnimento del sistema. L'unica differenza tra questi e i normali processi è che non inviano messaggi alla console o allo schermo in alcun modo.

Ecco come creare un demone su una macchina Linux.

Una breve introduzione a come vengono creati i demoni

Molti demoni vengono eseguiti sul sistema e alcuni esempi di demoni familiari sono i seguenti:

  • crond: esegue i comandi all'ora specificata
  • ssh: consente l'accesso al sistema da macchine remote
  • httpd: Serve pagine web
  • nfsd: consente la condivisione di file in rete

Inoltre, i processi daemon sono generalmente denominati per terminare con la lettera d, anche se non è obbligatorio.

Affinché un processo venga eseguito come demone, viene seguito il percorso seguente:

  • Le operazioni iniziali, come la lettura dei file di configurazione o l'ottenimento delle risorse di sistema necessarie, devono essere eseguite prima che il processo diventi un demone. In questo modo, il sistema può segnalare all'utente gli errori ricevuti e il processo verrà terminato con un codice di errore appropriato.
    instagram viewer
  • Viene creato un processo in esecuzione in background con init come processo padre. A tale scopo, un processo secondario viene prima biforcato dal processo init, quindi il processo superiore viene terminato con uscita.
  • Una nuova sessione dovrebbe essere aperta chiamando la funzione setid e il processo dovrebbe essere disconnesso dal terminale.
  • Tutti i descrittori di file aperti ereditati dal processo padre vengono chiusi.
  • Ingresso standard, uscitae i messaggi di errore vengono reindirizzati a /dev/null.
  • La directory di lavoro del processo deve cambiare.

Cosa sono le sessioni daemon?

Dopo aver effettuato l'accesso al sistema tramite un terminale, gli utenti possono eseguire molte applicazioni tramite il programma shell. Questi processi dovrebbero chiudersi quando l'utente esce dal sistema. Il sistema operativo raggruppa questi processi in sessioni e gruppi di processi.

Ogni sessione è composta da gruppi di processi. Puoi descrivere questa situazione come segue:

Il terminale in cui i processi ricevono i loro input e inviano i loro output è chiamato terminale di controllo. Un terminale di controllo è associato a una sola sessione alla volta.

Una sessione e i gruppi di processi in essa contenuti hanno numeri di identificazione (ID); questi numeri di identificazione sono i numeri di identificazione del processo (PID) dei leader della sessione e del gruppo di processo. Un processo figlio condivide lo stesso gruppo del processo padre. Quando lo sono più processi comunicare con il meccanismo del tubo, il primo processo diventa il leader del gruppo di processi.

Creazione di un processo demone su Linux

Qui vedrai come creare una funzione demone. A tale scopo, creerai una funzione denominata _demone. Puoi iniziare nominando il codice dell'applicazione che verrà eseguito come demone come prova.ce il codice con cui creerai la funzione demone demone.c.

//test.c
#includere <stdio.h>
int_demone(int, int);
intprincipale()
{
getchar();
_demone (0, 0);
getchar();
Restituzione0;
}
//daemon.c
#includere <sys/tipi.h>
#includere <sys/stat.h>
#includere <stdlib.h>
#includere <stdio.h>
#includere <fcntl.h>
#includere <unistd.h>
#includere <linux/fs.h>
#includere <linux/limits.h>
int_demone(int nochdir, int novicino){
pid_t pid;
pid = fork(); // Esegui il fork del processo padre
se (pid < 0) {
Uscita(EXIT_FAILURE);
}
se (pid > 0) {
Uscita(USCITA_SUCCESSO);
}
Restituzione0;
}

Per creare un demone, è necessario un processo in background il cui processo padre sia init. Nel codice sopra, _demone crea un processo figlio e quindi uccide il processo padre. In questo caso, il tuo nuovo processo sarà un sottoprocesso di init e continuerà a essere eseguito in background.

Ora compila l'applicazione con il comando seguente ed esamina lo stato del processo prima e dopo _diamante è chiamato:

gcc-otesttest.cdemone.c

Eseguire l'applicazione e passare a un altro terminale senza premere altri tasti:

./test

Puoi vedere che i valori relativi al tuo processo sono i seguenti. Qui, dovrai usare il comando ps per ottenere informazioni relative al processo. In questo caso, il _demone la funzione non è stata ancora chiamata.

ps -C test -o "pid ppid pgid sid tty statisticacomando"
# Produzione
PID PPID PGID SID TT STAT COMANDO
10296 5119 10296 5117 punti/2 S+ ./test

Quando guardi il STATISTICA campo, vedi che il tuo processo è in esecuzione ma è in attesa che si verifichi un evento fuori programma che ne causerà l'esecuzione in primo piano.

Abbreviazione Significato
S Aspettando addormentato che un evento accada
T Applicazione interrotta
S Capo sessione
+ L'applicazione è in esecuzione in primo piano

Puoi vedere che il processo padre della tua applicazione è la shell come previsto.

ps -jp 5119 
# Produzione
PID PGID SID TTY TIME CMD
5119 5119 5117 pts/2 00:00:02 zsh

Ora torna al terminale in cui stai eseguendo la tua applicazione e premi accedere invocare il _demone funzione. Quindi guarda di nuovo le informazioni sul processo sull'altro terminale.

ps -C test -o "pid ppid pgid sid tty statisticacomando"
# Produzione
PID PPID PGID SID TT STAT COMANDO
22504 1 22481 5117 pt/2 S ./test

Prima di tutto, puoi dire che il nuovo sottoprocesso è in esecuzione in background poiché non vedi il + personaggio nel STATISTICA campo. Ora esamina chi è il processo padre del processo usando il seguente comando:

ps -jp 1 
​​​​​​​# Produzione
PID PGID SID TTY TIME CMD
1 1 1? 00:00:01sistema

Ora puoi vedere che il processo padre del tuo processo è il sistema processi. È stato menzionato sopra che per il passaggio successivo dovrebbe essere aperta una nuova sessione e il processo dovrebbe essere disconnesso dal terminale di controllo. Per questo, usi la funzione setid. Aggiungi questa chiamata al tuo _demone funzione.

Il pezzo di codice da aggiungere è il seguente:

se (setsid() == -1) 
Restituzione-1;

Ora che hai già ispezionato lo stato _demone chiamato, ora puoi rimuovere il primo getchar funzione nel prova.c codice.

//test.c
#includere <stdio.h>
int_demone(int, int);
intprincipale()
{
_demone (0, 0);
getchar();
Restituzione0;
}

Dopo aver compilato ed eseguito nuovamente l'applicazione, vai al terminale in cui hai effettuato le recensioni. Il nuovo stato del tuo processo è il seguente:

ps -C test -o "pid ppid pgid sid tty statisticacomando"
​​​​​​​# Produzione
PID PPID PGID SID TT STAT COMANDO
25494 1 25494 25494? SS./test

Il ? firmare nel TT campo indica che il processo non è più connesso a un terminale. Si noti che il PID, PGID, e SID i valori del tuo processo sono gli stessi. Il tuo processo è ora un leader di sessione.

Nel passaggio successivo, cambia la directory di lavoro nella directory principale in base al valore dell'argomento passato. È possibile aggiungere il seguente snippet a _demone funzione per questo:

se (!nochdir) {
se (chdir("/") == -1)
Restituzione-1;
}

Ora, secondo l'argomento passato, tutti i descrittori di file possono essere chiusi. Aggiungi il seguente codice a _demone funzione:

#define NR_OPEN 1024
se (!noclose) {
per (io = 0; io < NR_APERTO; i++)
chiudere (i);
aprire("/dev/nullo", O_RDWR);
dup (0);
dup (0);
}

Dopo che tutti i descrittori di file sono stati chiusi, i nuovi file aperti dal demone verranno mostrati rispettivamente con i descrittori 0, 1 e 2. In questo caso, ad esempio, il stampa f i comandi nel codice verranno indirizzati al secondo file aperto. Per evitare ciò, i primi tre identificatori puntano a /dev/null dispositivo.

In questo caso, lo stato finale del _demone la funzione sarà la seguente:

#includere <sys/tipi.h>
#includere <sys/stat.h>
#includere <stdio.h>
#includere <stdlib.h>
#includere <fcntl.h>
#includere <errno.h>
#includere <unistd.h>
#includere <syslog.h>
#includere <stringa.h>
int_demone(vuoto){
// PID: ID processo
// SID: ID sessione
pid_t pid, sid;
pid = fork(); // Esegui il fork del processo padre
se (pid < 0) {
Uscita(EXIT_FAILURE);
}
se (pid > 0) {
Uscita(USCITA_SUCCESSO);
}
// Creare un SIDperbambino
sid = setid();
se (sid < 0) {
// FALLIRE
Uscita(EXIT_FAILURE);
}
se ((chdir("/")) < 0) {
// FALLIRE
Uscita(EXIT_FAILURE);
}
chiudi (STDIN_FILENO);
chiudi (STDOUT_FILENO);
chiudi (STDERR_FILENO);
mentre (1) {
// Alcuni compiti
dormire (30);
}
Uscita(USCITA_SUCCESSO);
}

Ecco un esempio di un frammento di codice che esegue il file ssh domanda come a demone:

...
if (!(debug_flag || inetd_flag || no_daemon_flag)) {
int fd;
se (demone (0, 0) < 0)
fatale("demone() non riuscito: %.200s", strerror (errno));
/* Disconnetti dal controllo tty. */
fd = aperto (_PATH_TTY, O_RDWR | O_NOCTTY);
se (fd >= 0) {
(vuoto) ioctl (fd, TIOCNOTTY, NULL);
chiudere (fd);
}
}
...

I demoni sono importanti per la programmazione del sistema Linux

I demoni sono programmi che eseguono varie azioni in un modo predefinito impostato in risposta a determinati eventi. Funzionano silenziosamente sulla tua macchina Linux. Non sono sotto il controllo diretto dell'utente e ogni servizio in esecuzione in background ha il suo demone.

È importante padroneggiare i demoni per apprendere la struttura del kernel del sistema operativo Linux e comprendere il funzionamento di varie architetture di sistema.

Cos'è un demone?

Leggi Avanti

CondividereTwittaCondividereE-mail

Argomenti correlati

  • Linux
  • kernel Linux
  • Programmazione
  • C Programmazione

Circa l'autore

Fatih Kuçükkarakurt (5 articoli pubblicati)

Un ingegnere e sviluppatore di software che è un fan della matematica e della tecnologia. Gli sono sempre piaciuti i computer, la matematica e la fisica. Ha sviluppato progetti di motori di gioco, machine learning, reti neurali artificiali e librerie di algebra lineare. Inoltre continua a lavorare su machine learning e matrici lineari.

Altro da Fatih Küçükkarakurt

Iscriviti alla nostra Newsletter

Iscriviti alla nostra newsletter per suggerimenti tecnici, recensioni, ebook gratuiti e offerte esclusive!

Clicca qui per iscriverti