Fork () and zombie process

Source: Internet
Author: User

[Email protected] Wangjing

For the fork () function, Unix/linux provides a fork () system call, and fork () returns two times at a time,

The operating system automatically copies a copy of the current process (called the parent process), which is then returned within the parent process and the child process, respectively;

The child process always returns 0, and the parent process returns the ID of the child process.

At the end of the parent process, the child process does not end immediately with the parent process, and the parent process does not wait for the child process to finish executing.

-Use of the fork () in Python

Example One

#!/usr/bin/python3import osprint (' Process (%s) start ... '% os.getpid ()) # only works on unix/linux/macpid = Os.fork () if PID  = = 0:    print (' I am child process (%s) and my parent is%s. '% (Os.getpid (), Os.getppid ())) Else:    print (' I (%s) just Created a child process (%s). '% (Os.getpid (), PID) ####### results ######## #Process (25912) Start ... I (25912) just created a child process (25913). I am Child process (25913) and my parent is 25912.

Example Two

#!/usr/bin/python3import osimport Time #创建子进程之前声明的变量source = 10try:    pid = os.fork ()    if pid = = 0: #子进程        print (' I am Child process (%s) and my parent is%s. '% (Os.getpid (), Os.getppid ()))        #在子进程中source自减1        Source-= 1 time        . Sleep (1)    else: #父进程        print (' I (%s) just created a child process (%s). '% (Os.getpid (), PID))    print (source) 
   
    time.sleep (2) except OSError as E:    print ("exception", E) ####### results ####### #I (12807) just created a child process (12 808). 10I am Child process (12808) and my parent is 12807.9
   

  

-How is the zombie process in the server generated?

Reference: https://www.cnblogs.com/yuxingfirst/p/3165407.html

Reference: http://blog.csdn.net/qq_20218109/article/details/52078076

Reference: http://blog.51cto.com/forlinux/1422438

when the child process is finished, but the parent process is not finished, the child process is out of the zombie state, which requires the parent process to collect the child process information to release the child process .

If the parent process ends the child process, the child process is pinned to the PID 1 process to manage it.

The purpose of setting the zombie state for a process is to maintain the child process information so that the parent process gets it at a later time,

This information includes the process ID of the child process, the termination status, and resource utilization information (CPU time, memory usage, and so on);

Examples of zombie process generation

The child process exits before the parent process, and the parent process does not call Wait/waitpid, and the child process becomes a zombie process.

#!/usr/bin/python3import osimport Time try:    pid = os.fork ()    if pid = = 0: #子进程        print (' I am child process (%s) a  nd my parent is%s. '% (Os.getpid (), Os.getppid ()))    else: #父进程        print (' I (%s) just created a child process (%s). '% (Os.getpid (), PID))        Time.sleep    print ('%s end '% os.getpid ()) except OSError as E:    print ("exception", e) ###### result ##### #I (19668) J UST created a child process (19669). I am Child process (19669) and my parent is 19668.19669 end19668 End   # This place sleep for 50 seconds before printing

When the program runs, combine the PS command to view the zombie process:

[Email protected] [13:30:40]$ ps-a-ostat,ppid,pid,cmd | Grep-e ' ^[zz] ' z+   19668 19669 [forkkk.py] <defunct>[email protected][13:31:28]$ [email protected][13:31:28]$ Ps-a-ostat,ppid,pid,cmd | grep forkkks+   10582 19668/usr/bin/python3./forkkk.pyz+   19668 19669 [forkkk.py] <defunct>    # Obviously the PID is 19669, that is, the ID of the child process, the child process has been executed, but the parent process 19668 has not finished executing. S+   

  

-How to avoid zombie processes/How to reclaim zombie processes? 1. Signal mode

When the child process exits, the kernel will give the parent process a SIGCHLD signal,

So we can set up a signal processing function that captures the SIGCHLD signal, call Wait (or waitpid) in the function body, and we can clean out the child process to prevent the zombie process.

#!/usr/bin/python3import osimport timeimport signaldef childhandler (*args, **kwargs): while True:try: result = Os.waitpid ( -1, OS. Wnohang) Except:break Else:print ("reaped child process% (PID) d, Status is% (status) s "% {' pid ': result[0], ' status ': Result[1]}) if __name__ = = ' __main__ ': signal.signal (signal. SIGCHLD, Childhandler) print ("Before the fork, parent pid is%s"% os.getpid ()) PID = Os.fork () if PID:PR Int ("Hello from the parent, the child pid is%s"% pid) print ("Parent sleeping seconds ...") Time.sleep (1    0) Print ("Parent sleep done.") Else:print ("Child sleeping 3 seconds ...") Time.sleep (3) print ("Child sleep done.") ###### results ##### #Before the fork, parent PID is 18998Hello from the parent, the child PID is 18999Parent sleeping second S ... Child sleeping 3 seconds ... Child sleep is done. Reaped child process 18999, status was 0Parent sleep done. 

Os.waitpid ()-1            indicates that all child processes waiting for the main process terminate the OS. Wnohang    indicates that if no child process has been terminated, it returns immediately.

2. Parent process Polls check subprocess and recycles
#!/usr/bin/python3import osimport timedef Recovery (): While True:try:result = Os.waitpid ( -1, OS. Wnohang) #result = os.wait () except:break else:return resultif __name__ = = ' __main__ ': Print ("Before the fork, parent pid is%s"% os.getpid ()) PID = Os.fork () if Pid:print ("Hell            O from the parent, the child PID was%s "% pid" while true:res = Recovery () time.sleep (0.5) Print (' one loop ... ') if res[0]: print ("reaped child process% (PID) d, Status is% (Statu s) S "% {' pid ': res[0], ' status ': Res[1]}) Break print (" Parent run End ... ") Else : Print ("Child sleeping 3 seconds ...") Time.sleep (3) print ("Child sleep done.") ###### results ##### #Before the fork, the parent PID is 3391Hello from the parent and the child PID is 3392Child sleeping 3 seconds. . One loop...one loop...one loop...one loop...one Loop...one Loop ... Child sleep Done.one Loop...one loop ... Reaped child process 3392, status is 0Parent run end ...

There is no way to handle the zombie process in a timely manner (depending on the polling interval).

Attention:

-result = Os.waitpid ( -1, OS. Wnohang) This method does not block the caller .

-result = os.wait () This will block the caller , resulting in no polling.

3. Fork () two times/python implementation daemon

The parent process once fork () produces a child process, and then the parent process immediately executes WAITPID (child process PID, NULL, 0) to wait for the child process to end , and then the Child Process fork () to generate the grandson process then immediately exit (0).

This way the process terminates successfully (the parent process simply takes the child process to the corpse, does not need the return value of the child process), and then the parent process resumes execution .

The grandson process is then forwarded to the init process for hosting because it loses its parent process (that is, the child process of the parent process).

So the parent process has no inheritance relationship with the grandson process, their parent process is init, and theinit process will automatically corpse at the end of its grandson process , so there will be no zombie process.

For details see: http://blog.tangyingkang.com/post/2016/10/20/python-daemon/ * * * *

Fork () two times is not required: 1190000008556669 * * * * *

Import Osimport sysimport atexitdef daemonize (pid_file=none): "" "Create Daemon:p Aram Pid_file: Save the Process ID file: return: "" "# Fork a subprocess out of the parent process out PID = Os.fork () # The PID of the subprocess must be 0, the parent process is greater than 0 if PID: # exits the parent process, the Sys.exit () method is more than the Os._exit () method Perform some refresh buffering work sys.exit (0) # The child process inherits the parent process's working directory by default, preferably a change to the root directory, or the Unload os.chdir ('/') # that affects the file system-the child process inherits the parent process's umask (file permission mask) by default, Reset to 0 (Full control) to avoid affecting the program to read and write files Os.umask (0) # Let the child process become the new session leader and process leader Os.setsid () # Note that this is the 2nd time Fork, which is the subprocess of the child process, we call it the grandson process _p id = os.fork () If _pid: # exit Subprocess sys.exit (0) # At this point, the grandson process is already a daemon, and then redirect the standard input, output, and error descriptors (redirected instead of closed, which prevents the program Error in print) # Flush buffer First, be careful to make the perpetual ship Sys.stdout.flush () Sys.stderr.flush () # dup2 function atomically Close and copy the file descriptor, redirecting to/dev/nul, which discards the There is an input output with open ('/dev/null ') as Read_null, open ('/dev/null ', ' W ') as Write_null:os.dup2 (Read_null.fileno (), SYS . Stdin.fileno ()) os.dup2 (Write_null.fileno (), Sys.stdout.fileno ()) os.dup2 (Write_null.fileno (), SYS.STDERR.F   Ileno ()) # write PID file If Pid_file:with open (pid_file, ' w+ ') as F:f.write (str (os.getpid ())) # Registers the Exit function and removes the PID file when the process exits abnormally Atexit.register (Os.remove, Pid_file)

-Extension: The cost of fork in Python

Fork () and zombie process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.