Daemonize a Python process

Introduction

I read the book I see, Unix processes-the basics of Unix learned in Ruby. It explains the concept of a process using Ruby code. I was impressed with the very easy-to-understand book: joy:

I would like to replace some of the Ruby code in the book with Python for review. Since it's a big deal, I implemented the process daemonization that I thought was the most practical.

code

from datetime import datetime
import os
import sys
import time


def daemonize():
  """
Daemonize the process.
  """
  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():
  """
Outputs a text file with the current time as the file name.
The process pid that output this file is entered in the file.
  """
  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):
  """
interval create every second_empty_file()To call.
  """
  while True:
    create_empty_file()
    time.sleep(interval)


if __name__ == '__main__':
  daemonize()
  create_empty_files()

Description of daemonize ()

About the first os.fork ()

The code above calls fork () twice.

def fork()
  if os.fork():
    sys.exit()

In os.fork (), the pid of the child process is returned in the parent process, and 0 is returned in the child process. That is, the parent process terminates and the child process survives.

About os.setsid ()

os.setsid () is as its name suggests setsid () /html/LDP_man-pages/man2/setsid.2.html) Invoke the system call. And setsid () does three things [^ 1]:

  1. Create a new session.
  2. Make the calling process the leader of a new session.
  3. Detach the process from the control terminal.

This causes the child process that called os.setsid () to become the leader of the new session (and the new process group for that session) and no longer have a controlling terminal. However, it seems that it is technically possible to reset the control terminal to a session [^ 2].

About the second os.fork ()

The second os.fork () terminates the process that was the leader of the session and process group and spawns a new child process. Since the terminated session reader has no control terminal, and the new child process is not the session leader, this can guarantee that it will never have a control terminal. The daemon process is complete.

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

Throw away all standard streams by sending them to / dev / null. This is because the daemon process does not have a controlling terminal, so these resources are no longer needed. The reason why the standard stream is sent to / dev / null instead of closing is that the standard stream is still available from the outside in consideration of the external program that assumes the use of the standard stream. It seems to be to make it look like it is.

Execution result

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

A handmade daemon process keeps running in the background: innocent:

at the end

If you feel like it, I want to read the code of python-daemon: sunglasses:

reference

Books

Web

[^ 1]: It is assumed that the calling process is not the process group leader. [^ 2]: No details are mentioned in the book. In the article Unix daemon mechanism, "Old System V In the wiki / UNIX_System_V) system, I was able to connect the control terminal to the session leader process later, so I am doing it for historical reasons. "

Recommended Posts

Daemonize a Python process
Daemonize a Python web app with Supervisor
A memorandum of python string deletion process
A * algorithm (Python edition)
Create a Python module
A python lambda expression ...
Note to daemonize python
Create a Python environment
Python3> round (a --b, 7)
I made a login / logout process using Python Bottle.
Take a screenshot in Python
Create a dictionary in Python
AtCoder ABC 178 Python (A ~ E)
A road to intermediate Python
[Python] Use a string sequence
AtCoder ABC 176 Python (A ~ E)
Python list is not a list
A memorandum about correlation [Python]
Make a bookmarklet in Python
Building a Python virtual environment
Create a python numpy array
Make a fortune with Python
I made a python text
A memorandum about Python mock
AtCoder ABC 182 Python (A ~ D)
Build a Python environment offline
Draw a heart in Python
Create a directory with python
Building a Python virtual environment
[Python] Dynamic programming TDPC A
Process feedly xml with Python.
What is a python map?
A note about [python] __debug__
Building a Python environment on Mac
Python a + = b and a = a + b are different
A record of patching a python package
[Python] What is a zip function?
[Python] What is a with statement?
Write a binary search in Python
Use pymol as a python library
Solve ABC163 A ~ C with Python
Operate a receipt printer with python
A python graphing manual with Matplotlib.
Touch a Python object from Elixir
Hit a command in Python (Windows)
I made a Line-bot using Python!
Python
ABC127 A, B, C Explanation (python)
Create a python GUI using tkinter
Create a DI Container in Python
IQ Bot Custom Logic (Python): Efficient replacement process in a loop
Building a Python environment on Ubuntu
Python: A Note About Classes 1 "Abstract"
Drawing a silverstone curve using python
Process Splunk execution results using Python and save to a file
Solve ABC166 A ~ D with Python
Do you need a Python re.compile?
Draw a scatterplot matrix in python
A brief summary of Python collections
ABC166 in Python A ~ C problem
Create a virtual environment with Python!