logo

forker.py

On peut trouver sur the Python Package Index (PyPI) un outil intéressant pour transformer du code python en html : py2html 0.62

Évidemment, après, je me suis demandé quel bout de code utiliser pour essayer ce script. Voici donc forker.py, un petit bout de code d'une page qui me sers à «démoniser» lors d'un appel de fonction.

Ce code est directement inspiré de cette recette du Python Cookbook.
Il permet de «forker» le process en cours lors d'un appel de fonction, et de le faire tourner en arrière plan indépendamment du contexte initial (mode démon). Cet exemple fonctionne, je l'utilise dans plusieurs programmes.

Le code source

Voici le code source :

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# $Source$

# _include_licence_

import os
import sys

__version__ = "$Id: forker.py.html 2337 2005-05-13 23:42:37Z jd $"

def raz_file_descriptor(): 
    try: 
        maxfd = os.sysconf("SC_OPEN_MAX")
    except (AttributeError, ValueError): 
        maxfd = 256 # default maximum

    for fd in range(0, maxfd): 
        try: 
            os.close(fd)
        except OSError: # ERROR (ignore)
            pass

    # Redirect the standard file descriptors to /dev/null.
    os.open("/dev/null", os.O_RDONLY)# standard input (0)
    os.open("/dev/null", os.O_RDWR)# standard output (1)
    os.open("/dev/null", os.O_RDWR)# standard error (2)

def forker(fonction, *args): 
    # first, let's fork
    pid = os.fork()
    if pid == 0: 
        #we are child
        os.setsid()
        # second fork
        mpid = os.fork()
        if mpid == 0: 
            # we are the second child
            raz_file_descriptor()
            fonction(*args)
            os._exit(0)
        else: 
            # still 1st child
            try: 
                os.waitpid(mpid, os.WNOHANG)
            except: 
                pass
            os._exit(0)
    else: 
        # we are still there, continue our duty
        try: 
            os.waitpid(pid, os.WNOHANG)
        except: 
            pass
        return

if __name__ == "__main__": 
    import time
    def forked_funct(delay): 
        "test fonction: open a file, wait delay second, close the file."
        pid = os.getpid()
        of = open("./test_forker_%s"%pid, "w")
        of.write("Start  %s\n"%time.asctime())
        of.write("waiting %s sec.\n"%delay)
        time.sleep(delay)
        of.write("End    %s\n"%time.asctime())
        of.close()
        return

    forker(forked_funct, 10)
    forker(forked_funct, 8)
    forker(forked_funct, 12)

Fichiers