Python implements the compiling of the daemon in Linux, and the python daemon
The example in this article describes how to compile the daemon process of Python in Linux. It is for your reference and I believe it will be helpful for your Python program design. The specific method is as follows:
1. Call fork () so that the parent process can exit. In this way, the control is returned to the command line or shell program that runs your program.This step is required to ensure that the new process is not a process group leader ). Next, 'setsid () 'will fail because you are the process leader in the process group. When a process calls the fork function, the operating system creates a new sub-process, which is essentially the same as the parent process. Child processes inherit copies of multiple values from the parent process, such as global variables and environment variables. The only difference between the two processes is the return value of fork. The child process receives the return value 0, while the parent process receives the pid of the child process as the return value. After the fork function is called, the two processes concurrently execute the same program. The first execution is the next line of code after the fork function is called. Parent and Child processes run concurrently and are independent of each other. That is to say, they are "Asynchronous.
2. Call 'setsid () 'to become the frontend process of a process group and session group.. Since a control terminal is associated with a session, and this new session has not yet obtained a control terminal, our process has no control terminal, which is a good thing for the daemon.
3. Call 'fork () 'again, so the parent process (Session group header process) can exit.. This means that a non-session Group's leading process can never regain control terminals.
4. Call 'chdir ("/") 'to make sure that our processes do not keep any directories in use.. Otherwise, the system administrator cannot unload a file system because it is our current working directory. [Similarly, we can change the current directory to the directory where the files that are important to the daemon program runs]
5. Call 'umask (0) 'so that we have full control over anything we write.We don't know what umask we inherit. [This step is optional] (Translator's note: this refers to step 5, because the daemon does not necessarily need to write files)
6. Call 'close () 'to close file descriptors 0, 1 and 2. In this way, we release the standard input, standard output, and standard error output inherited from the parent process.We can't know where these file descriptors may have been redirected. Note that many daemon use 'sysconf () 'to confirm the' _ SC _OPEN_MAX 'restriction. '_ SC _OPEN_MAX' tells you the maximum number of files that each process can open. Then, with a loop, the daemon can close all possible file descriptors. You must decide whether to do this or not. If you think there may be opened file descriptors, You need to disable them because the system has a limit on the number of files opened at the same time.
7. Create a new file descriptor for standard input, standard output, and standard error output.Even if you don't want to use them, opening them is a good idea. Accurate operations on these descriptors are based on their own interests. For example, if you have a log file, you may want to open it as a standard output or a standard error output, open '/dev/null' as the standard input; as an alternative, you can open'/dev/console' as the standard error output and/or standard output, '/dev/null' is a standard input, or any other method that makes sense to your daemon. Note: The dup2 function is generally used to atomically close and copy file descriptors.
The implementation code is as follows:
# Core modules importatexit importos importsys importtime importsignal classDaemon(object): """ A generic daemon class. Usage: subclass the Daemon class and override the run() method """ def __init__(self, pidfile, stdin=os.devnull, stdout=os.devnull, stderr=os.devnull, home_dir='.', umask=022, verbose=1): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.pidfile = pidfile self.home_dir = home_dir self.verbose = verbose self.umask = umask self.daemon_alive = True def daemonize(self): """ Do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) """ try: pid = os.fork() if pid > 0: # Exit first parent sys.exit(0) except OSError, e: sys.stderr.write( "fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # Decouple from parent environment os.chdir(self.home_dir) os.setsid() os.umask(self.umask) # Do second fork try: pid = os.fork() if pid > 0: # Exit from second parent sys.exit(0) except OSError, e: sys.stderr.write( "fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) if sys.platform != 'darwin': # This block breaks on OS X # Redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() si = file(self.stdin, 'r') so = file(self.stdout, 'a+') if self.stderr: se = file(self.stderr, 'a+', 0) else: se = so os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) def sigtermhandler(signum, frame): self.daemon_alive = False signal.signal(signal.SIGTERM, sigtermhandler) signal.signal(signal.SIGINT, sigtermhandler) if self.verbose >= 1: print "Started" # Write pidfile atexit.register( self.delpid) # Make sure pid file is removed if we quit pid = str(os.getpid()) file(self.pidfile, 'w+').write("%s\n" % pid) def delpid(self): os.remove(self.pidfile) def start(self, *args, **kwargs): """ Start the daemon """ if self.verbose >= 1: print "Starting..." # Check for a pidfile to see if the daemon already runs try: pf = file(self.pidfile, 'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None except SystemExit: pid = None if pid: message = "pidfile %s already exists. Is it already running?\n" sys.stderr.write(message % self.pidfile) sys.exit(1) # Start the daemon self.daemonize() self.run(*args, **kwargs) def stop(self): """ Stop the daemon """ if self.verbose >= 1: print "Stopping..." # Get the pid from the pidfile pid = self.get_pid() if not pid: message = "pidfile %s does not exist. Not running?\n" sys.stderr.write(message % self.pidfile) # Just to be sure. A ValueError might occur if the PID file is # empty but does actually exist if os.path.exists(self.pidfile): os.remove(self.pidfile) return # Not an error in a restart # Try killing the daemon process try: i = 0 while 1: os.kill(pid, signal.SIGTERM) time.sleep(0.1) i = i + 1 if i % 10 == 0: os.kill(pid, signal.SIGHUP) except OSError, err: err = str(err) if err.find("No such process") > 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: print str(err) sys.exit(1) if self.verbose >= 1: print "Stopped" def restart(self): """ Restart the daemon """ self.stop() self.start() def get_pid(self): try: pf = file(self.pidfile, 'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None except SystemExit: pid = None return pid def is_running(self): pid = self.get_pid() print(pid) return pid and os.path.exists('/proc/%d' % pid) def run(self): """ You should override this method when you subclass Daemon. It will be called after the process has been daemonized by start() or restart(). """
Interested readers can debug and run the instance code in this article. I believe there will be new gains.
What is the concept of a daemon in Linux? What is daemonpy?
1. daemon is a process that does not meet you but does not work for you (daemon you) in the background. It may be working for you all the time, or it may be waiting for you to "get it right when you need it" (the CPU will not be occupied when you wait ). Just like a service in Windows.
2. Like killing the daemon and other processes, first identify the PID of the process (process number ):
Ps-ef
Then run the kill command.
Kill-9 XXX (XXX is the PID you just found)
3. py refers to python, and python is a programming language .. Py is a program with python.
4. Most daemon can start it like other programs. Some daemon processes are an application.
To call it, or start it by running a software or script.
Supplement: Do not kill the daemon. It is dangerous.
Writing daemon in linux
Redirection is required because all terminals are gone.
By default, these three descriptors are terminal-based. After the terminals are gone, they are redirected to files so that they are still available.
The so-called "depends on the terminal to work" is the default situation