Dämonisiere einen Python-Prozess

Einführung

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.

Code

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()

Beschreibung von daemonize ()

Über die erste os.fork ()

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.

Über os.setsid ()

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]:

  1. Erstellen Sie eine neue Sitzung.
  2. Machen Sie den Anrufprozess zum Leiter einer neuen Sitzung.
  3. Trennen Sie den Prozess vom Steuerterminal.

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].

Über die zweite os.fork ()

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.

Über throw_away_io ()

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.

Ausführungsergebnis

$ 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:

schließlich

Wenn Sie Lust dazu haben, möchte ich den Code von python-daemon lesen: sunglasses:

Referenz

Bücher

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

Dämonisiere einen Python-Prozess
Dämonisieren Sie eine Python-Webanwendung mit Supervisor
Memorandum zum Löschen von Python-Strings
Ein * Algorithmus (Python Edition)
Erstellen Sie ein Python-Modul
Pythons Lambda-Ausdruck ...
Beachten Sie, dass Python ein Daemon ist
Erstellen Sie eine Python-Umgebung
Python3> rund (a - b, 7)
Ich habe einen Anmelde- / Abmeldevorgang mit Python's Bottle durchgeführt.
Machen Sie einen Screenshot in Python
Erstellen Sie ein Wörterbuch in Python
AtCoder ABC 178 Python (A ~ E)
Ein Weg zum mittleren Python
[Python] Verwenden Sie eine Zeichenfolgenfolge
AtCoder ABC 176 Python (A ~ E)
Memorandum über Korrelation [Python]
Erstellen Sie ein Lesezeichen in Python
Erstellen einer virtuellen Python-Umgebung
Erstellen Sie ein Python-Numpy-Array
Machen Sie eine Lotterie mit Python
Ich habe einen Python-Text gemacht
Ein Memorandum über den Python-Mock
AtCoder ABC 182 Python (A ~ D)
Erstellen Sie die Python-Umgebung offline
Zeichne ein Herz in Python
Erstellen Sie ein Verzeichnis mit Python
Erstellen einer virtuellen Python-Umgebung
Verarbeiten Sie Feedly-XML mit Python.
Ein Hinweis zu [Python] __debug__
Erstellen einer Python-Umgebung auf einem Mac
Python a + = b und a = a + b sind unterschiedlich
Eine Aufzeichnung zum Patchen eines Python-Pakets
[Python] Was ist eine Zip-Funktion?
[Python] Was ist eine with-Anweisung?
Schreiben Sie eine Dichotomie in Python
Verwenden Sie Pymol als Python-Bibliothek
Löse ABC163 A ~ C mit Python
Bedienen Sie den Belegdrucker mit Python
Python-Grafikhandbuch mit Matplotlib.
Berühren Sie Python-Objekte in Elixir
Drücken Sie einen Befehl in Python (Windows)
Ich habe einen Line-Bot mit Python gemacht!
Python
ABC127 A, B, C Erklärung (Python)
Erstellen Sie mit tkinter eine Python-GUI
Erstellen Sie einen DI-Container mit Python
IQ Bot Custom Logic (Python): Optimieren Sie die Ersetzungsverarbeitung in einer Schleife
Erstellen einer Python-Umgebung unter Ubuntu
Python: Ein Hinweis zu Klasse 1 "Abstract"
Zeichnen einer Silbersteinkurve mit Python
Verarbeiten Sie das Ausführungsergebnis von Splunk mit Python und speichern Sie es in einer Datei
Löse ABC166 A ~ D mit Python
Benötigen Sie Python re.compile?
Zeichnen Sie eine Streudiagrammmatrix mit Python
Eine kurze Zusammenfassung der Python-Sammlung
ABC166 in Python A ~ C Problem
Erstellen Sie eine virtuelle Umgebung mit Python!