Ich habe das Buch Ich sehe, Unix-Prozess - die Grundlagen von Unix in Ruby gelernt gelesen. Es erklärt das Konzept eines Prozesses mit Ruby-Code. Ich war beeindruckt von dem sehr leicht verständlichen Buch: Freude:
Ich möchte einen Teil des Ruby-Codes im Buch zur Überprüfung durch Python ersetzen. Da es eine große Sache ist, habe ich die Prozessdämonisierung implementiert, die ich für die praktischste hielt.
from datetime import datetime
import os
import sys
import time
def daemonize():
"""
Machen Sie den Prozess zu einem Daemon.
"""
def fork():
if os.fork():
sys.exit()
def throw_away_io():
stdin = open(os.devnull, 'rb')
stdout = open(os.devnull, 'ab+')
stderr = open(os.devnull, 'ab+', 0)
for (null_io, std_io) in zip((stdin, stdout, stderr),
(sys.stdin, sys.stdout, sys.stderr)):
os.dup2(null_io.fileno(), std_io.fileno())
fork()
os.setsid()
fork()
throw_away_io()
def create_empty_file():
"""
Gibt eine Textdatei mit der aktuellen Uhrzeit als Dateinamen aus.
Die Prozess-PID, die diese Datei ausgibt, wird in die Datei eingegeben.
"""
now = datetime.now().strftime('%Y%m%d%H%M%S')
filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)),
f'tmp/{now}.txt')
with open(filepath, 'w') as f:
f.write(str(os.getpid()))
def create_empty_files(interval=60):
"""
Intervall erstellen jede Sekunde_empty_file()Anrufen.
"""
while True:
create_empty_file()
time.sleep(interval)
if __name__ == '__main__':
daemonize()
create_empty_files()
Der obige Code ruft zweimal fork () auf.
def fork()
if os.fork():
sys.exit()
In os.fork () wird die PID des untergeordneten Prozesses im übergeordneten Prozess und 0 im untergeordneten Prozess zurückgegeben. Das heißt, der übergeordnete Prozess wird beendet und der untergeordnete Prozess überlebt.
os.setsid () ist wie der Name schon sagt setsid () /html/LDP_man-pages/man2/setsid.2.html) Ruft einen Systemaufruf auf. Und setsid () macht drei Dinge [^ 1]:
Dadurch wird der untergeordnete Prozess, der os.setsid () aufgerufen hat, zum Leiter der neuen Sitzung (und der neuen Prozessgruppe für diese Sitzung) und verfügt nicht mehr über ein steuerndes Terminal. Es scheint jedoch technisch möglich zu sein, das Steuerterminal auf eine Sitzung zurückzusetzen [^ 2].
Das zweite os.fork () beendet den Prozess, der der Leiter der Sitzung und der Prozessgruppe war, und erzeugt einen neuen untergeordneten Prozess. Da der abgebrochene Sitzungsleiter kein Steuerterminal hat und der neue untergeordnete Prozess nicht der Sitzungsleiter ist, kann dies garantieren, dass er niemals ein Steuerterminal haben wird. Der Daemon-Prozess ist abgeschlossen.
def throw_away_io():
stdin = open(os.devnull, 'rb')
stdout = open(os.devnull, 'ab+')
stderr = open(os.devnull, 'ab+', 0)
for (null_io, std_io) in zip((stdin, stdout, stderr),
(sys.stdin, sys.stdout, sys.stderr)):
os.dup2(null_io.fileno(), std_io.fileno())
Werfen Sie alle Standard-Streams weg, indem Sie sie an / dev / null
senden. Dies liegt daran, dass der Daemon-Prozess kein Steuerterminal hat und diese Ressourcen nicht mehr benötigt werden. Der Grund, warum der Standard-Stream an "/ dev / null" gesendet wird, anstatt ihn zu schließen, besteht darin, dass der Standard-Stream unter Berücksichtigung des externen Programms, das die Verwendung des Standard-Streams übernimmt, weiterhin von außen verfügbar ist. Es scheint so zu sein, dass es so aussieht, wie es ist.
$ python main.py
$ ps aux | grep -v grep | grep python
quanon 4621 0.0 0.0 2418360 2996 ?? S 11:46PM 0:00.00 python main.py
$ cat tmp/20170520234627.txt
4621⏎
Ein handgemachter Dämonenprozess läuft im Hintergrund weiter: unschuldig:
Wenn Sie Lust dazu haben, möchte ich den Code von python-daemon lesen: sunglasses:
Web
[^ 1]: Es wird angenommen, dass der aufrufende Prozess nicht der Prozessgruppenleiter ist. [^ 2]: Im Buch werden keine Details erwähnt. In dem Artikel Unix-Daemon-Mechanismus, "Old System V" Im Wiki / UNIX_System_V) -System konnte ich das Steuerterminal später mit dem Sitzungsleiterprozess verbinden, daher mache ich das aus historischen Gründen. "
Recommended Posts