Demony to procesy, które nie działają bezpośrednio pod kontrolą użytkownika, ale działają w tle. Zwykle rozpoczynają się przy starcie systemu i działają nieprzerwanie, aż system się wyłączy. Jedyną różnicą między tymi a normalnymi procesami jest to, że w żaden sposób nie wysyłają komunikatów do konsoli lub ekranu.

Oto jak stworzyć demona na maszynie z Linuksem.

Krótkie wprowadzenie do tworzenia demonów

W systemie działa wiele demonów, a niektóre znane przykłady demonów są następujące:

  • krąg: Sprawia, że ​​polecenia są uruchamiane w określonym czasie
  • sshd: Umożliwia logowanie do systemu ze zdalnych maszyn
  • httpd: Obsługuje strony internetowe
  • nfsd: Umożliwia udostępnianie plików przez sieć

Ponadto procesy demonów są zwykle nazywane tak, aby kończyły się literą d, chociaż nie jest to obowiązkowe.

Aby proces działał jako demon, postępuj zgodnie z następującą ścieżką:

  • Operacje początkowe, takie jak odczytywanie plików konfiguracyjnych lub uzyskiwanie niezbędnych zasobów systemowych, muszą zostać wykonane, zanim proces stanie się demonem. W ten sposób system może zgłosić otrzymane błędy użytkownikowi, a proces zostanie zakończony odpowiednim kodem błędu.
    instagram viewer
  • Proces działający w tle jest tworzony z init jako procesem nadrzędnym. W tym celu najpierw rozwidla się podproces z procesu init, a następnie proces górny kończy się wyjściem.
  • Nowa sesja powinna zostać otwarta przez wywołanie funkcji setsid, a proces powinien zostać odłączony od terminala.
  • Wszystkie otwarte deskryptory plików odziedziczone z procesu nadrzędnego są zamykane.
  • Standardowe wejście, wyjście, a komunikaty o błędach są przekierowywane do /dev/null.
  • Katalog roboczy procesu musi się zmienić.

Co to są sesje demonów?

Po zalogowaniu się do systemu za pomocą terminala, użytkownicy mogą uruchamiać wiele aplikacji za pośrednictwem programu powłoki. Procesy te powinny zostać zamknięte, gdy użytkownik wyjdzie z systemu. System operacyjny grupuje te procesy w grupy sesji i procesów.

Każda sesja składa się z grup procesów. Możesz opisać tę sytuację w następujący sposób:

Terminal, w którym procesy odbierają dane wejściowe i wysyłają swoje dane wyjściowe, nazywany jest terminalem sterującym. Terminal sterujący jest powiązany tylko z jedną sesją na raz.

Sesja i znajdujące się w niej grupy procesów mają numery identyfikacyjne (ID); te numery identyfikacyjne są numerami identyfikacyjnymi procesu (PID) liderów sesji i grup procesów. Proces potomny dzieli tę samą grupę, co jego proces nadrzędny. Gdy wiele procesów jest komunikacja z mechanizmem rurowym, pierwszy proces staje się liderem grupy procesów.

Tworzenie procesu demona w systemie Linux

Tutaj zobaczysz, jak możesz stworzyć funkcję demona. W tym celu utworzysz funkcję o nazwie _demon. Możesz zacząć od nazwania kodu aplikacji, która będzie działała jako demon, jako test.ci kod, który utworzysz funkcję demona jako demon.c.

//test.c
#włączać <stdio.h>
int_demon(int, int);
intGłówny()
{
getchar();
_demon (0, 0);
getchar();
zwrócić0;
}
//daemon.c
#włączać <sys/types.h>
#włączać <sys/stat.h>
#włączać <stdlib.h>
#włączać <stdio.h>
#włączać <fcntl.h>
#włączać <unistd.h>
#włączać <linux/fs.h>
#włączać <linux/limits.h>
int_demon(int nochdir, int nie zamknij){
pid_t pid;
pid = widelec(); // rozwidlenie procesu nadrzędnego
jeśli (pid < 0) {
Wyjście(EXIT_FAILURE);
}
jeśli (pid > 0) {
Wyjście(EXIT_SUCCESS);
}
zwrócić0;
}

Aby utworzyć demona, potrzebujesz procesu w tle, którego procesem nadrzędnym jest init. W powyższym kodzie _demon tworzy proces potomny, a następnie zabija proces nadrzędny. W takim przypadku nowy proces będzie podprocesem init i będzie nadal działał w tle.

Teraz skompiluj aplikację za pomocą następującego polecenia i sprawdź stan procesu przed i po _deamon jest nazywany:

gcc-otesttest.cdemon.c

Uruchom aplikację i przełącz się na inny terminal bez naciskania innych klawiszy:

./test

Widać, że wartości związane z twoim procesem są następujące. Tutaj będziesz musiał użyć polecenie ps, aby uzyskać informacje związane z procesem. W tym przypadku _demon funkcja nie została jeszcze wywołana.

ps -C test -o "pid ppid pgid sid tty statKomenda"
# Wyjście
PID PPID PGID SID TT STAT POLECENIE
10296 5119 10296 5117 pkt/2 S+ ./test

Kiedy patrzysz na STATYSTYKA widzisz, że twój proces działa, ale czeka na wystąpienie zdarzenia poza harmonogramem, które spowoduje jego uruchomienie na pierwszym planie.

Skrót Oznaczający
S Czekam śpiąc na wydarzenie
T Aplikacja zatrzymana
s Lider sesji
+ Aplikacja działa na pierwszym planie

Możesz zobaczyć, że proces nadrzędny Twojej aplikacji jest powłoką, zgodnie z oczekiwaniami.

ps-jp 5119 
# Wyjście
PID PGID SID TTY CZAS CMD
5119 5119 5117 pkt/2 00:00:02 zsh

Teraz wróć do terminala, na którym uruchomiona jest Twoja aplikacja, i naciśnij Wchodzić przywoływać _demon funkcjonować. Następnie ponownie spójrz na informacje o procesie na drugim terminalu.

ps -C test -o "pid ppid pgid sid tty statKomenda"
# Wyjście
PID PPID PGID SID TT STAT POLECENIE
22504 1 22481 5117 pkt/2 szt./test

Przede wszystkim możesz powiedzieć, że nowy podproces działa w tle, ponieważ nie widzisz + postać w STATYSTYKA pole. Teraz sprawdź, kto jest procesem nadrzędnym procesu, używając następującego polecenia:

ps -jp 1 
​​​​​​​# Wyjście
PID PGID SID TTY CZAS CMD
1 1 1? 00:00:01systemd

Możesz teraz zobaczyć, że nadrzędnym procesem twojego procesu jest systemd proces. Wspomniano powyżej, że w następnym kroku powinna zostać otwarta nowa sesja, a proces powinien zostać odłączony od terminala kontrolnego. W tym celu użyj funkcji setsid. Dodaj to połączenie do swojego _demon funkcjonować.

Fragment kodu do dodania jest następujący:

if (setsid() == -1) 
zwrócić-1;

Teraz, gdy już wcześniej sprawdzałeś stan _demon zadzwonił, możesz teraz usunąć pierwszy dostaćchar funkcja w test.c kod.

//test.c
#włączać <stdio.h>
int_demon(int, int);
intGłówny()
{
_demon (0, 0);
getchar();
zwrócić0;
}

Po skompilowaniu i ponownym uruchomieniu aplikacji przejdź do terminala, w którym dokonałeś recenzji. Nowy status Twojego procesu wygląda następująco:

ps -C test -o "pid ppid pgid sid tty statKomenda"
​​​​​​​# Wyjście
PID PPID PGID SID TT STAT POLECENIE
25494 1 25494 25494? SS ./test

ten ? zaloguj się TT pole wskazuje, że twój proces nie jest już połączony z terminalem. Zauważ, że PID, PGID, oraz SID wartości twojego procesu są takie same. Twój proces jest teraz liderem sesji.

W następnym kroku zmień katalog roboczy na katalog główny zgodnie z wartością przekazanego argumentu. Możesz dodać następujący fragment kodu do _demon funkcja do tego:

jeśli (!nochdir) {
jeśli (chdir("/") == -1)
zwrócić-1;
}

Teraz, zgodnie z przekazanym argumentem, wszystkie deskryptory plików można zamknąć. Dodaj następujący kod do _demon funkcjonować:

#define NR_OPEN 1024
jeśli (!noclose) {
dla (i = 0; i < NR_OPEN; i++)
zamknij (i);
otwarty("/dev/zero", O_RDWR);
dupa (0);
dupa (0);
}

Po zamknięciu wszystkich deskryptorów plików nowe pliki otwierane przez demona będą wyświetlane z deskryptorami odpowiednio 0, 1 i 2. W tym przypadku na przykład drukuj polecenia w kodzie zostaną skierowane do drugiego otwartego pliku. Aby tego uniknąć, pierwsze trzy identyfikatory wskazują na /dev/null urządzenie.

W tym przypadku stan końcowy _demon funkcja będzie wyglądać następująco:

#włączać <sys/types.h>
#włączać <sys/stat.h>
#włączać <stdio.h>
#włączać <stdlib.h>
#włączać <fcntl.h>
#włączać <errno.h>
#włączać <unistd.h>
#włączać <syslog.h>
#włączać <string.h>
int_demon(próżnia){
// PID: identyfikator procesu
// SID: identyfikator sesji
pid_t pid, sid;
pid = widelec(); // rozwidlenie procesu nadrzędnego
jeśli (pid < 0) {
Wyjście(EXIT_FAILURE);
}
jeśli (pid > 0) {
Wyjście(EXIT_SUCCESS);
}
// Tworzyć a SIDdladziecko
identyfikator = identyfikator_zestawu();
jeśli (sid < 0) {
// PONIEŚĆ PORAŻKĘ
Wyjście(EXIT_FAILURE);
}
jeśli ((chdir("/")) < 0) {
// PONIEŚĆ PORAŻKĘ
Wyjście(EXIT_FAILURE);
}
zamknij (STDIN_FILENO);
zamknij (STDOUT_FILENO);
zamknij (STDERR_FILENO);
chwila (1) {
// Niektóre zadania
sen (30);
}
Wyjście(EXIT_SUCCESS);
}

Oto przykład fragmentu kodu, który uruchamia sshd aplikacja jako demon:

...
if (!(debug_flag || inetd_flag || no_daemon_flag)) {
int fd;
jeśli (demon (0, 0) < 0)
fatalny("demon() nie powiódł się: %.200s", strerror (errno));
/* Rozłącz się z kontrolującym tty. */
fd = otwarte (_PATH_TTY, O_RDWR | O_NOCTTY);
jeśli (fd >= 0) {
(próżnia) ioctl (fd, TIOCNOTTY, NULL);
zamknij (fd);
}
}
...

Demony są ważne dla programowania systemu Linux

Demony to programy, które wykonują różne akcje w predefiniowany sposób w odpowiedzi na określone zdarzenia. Działają cicho na twoim komputerze z systemem Linux. Nie znajdują się pod bezpośrednią kontrolą użytkownika, a każda usługa działająca w tle ma swojego demona.

Ważne jest, aby opanować demony, aby poznać strukturę jądra systemu operacyjnego Linux i zrozumieć działanie różnych architektur systemowych.

Co to jest demon?

Czytaj dalej

UdziałĆwierkaćUdziałE-mail

Powiązane tematy

  • Linux
  • Jądro Linuksa
  • Programowanie
  • Programowanie C

O autorze

Fatih Küçükkarakurt (5 opublikowanych artykułów)

Inżynier i programista, pasjonat matematyki i technologii. Zawsze lubił komputery, matematykę i fizykę. Opracował projekty silników gier, a także uczenie maszynowe, sztuczne sieci neuronowe i biblioteki algebry liniowej. Ponadto kontynuuje prace nad uczeniem maszynowym i macierzami liniowymi.

Więcej od Fatiha Küçükkarakurt

Zapisz się do naszego newslettera

Dołącz do naszego newslettera, aby otrzymywać porady techniczne, recenzje, bezpłatne e-booki i ekskluzywne oferty!

Kliknij tutaj, aby zasubskrybować