Re: Bug help: CGI forking

Discussion in 'Python' started by Robin Munn, Aug 1, 2003.

  1. Robin Munn

    Robin Munn Guest

    Jonathan Hayward <> wrote:
    > I am trying to have a CGI script which forks a daemon the first time,
    > and on subsequent times asks the daemon to do all the work. The daemon
    > and the CGI script are run by the same code.
    >
    > I'm trying to have a class that will handle daemon multithreading, the
    > "hollow shell" CGI script starting up the daemon, and the CGI script
    > talking with the daemon. I tried to use recipes from O'Reilly's
    > _Python Cookbook_, but I must have messed up. The script usually
    > hangs, and when it doesn't hang, the daemon sometimes isn't started. I
    > think I have a fork bug, at least.
    >
    > Any bugfixes and/or clarifications welcome:
    >
    > class multitasking_manager(ancestor):
    > """Class to handle multithreading and multiprocessing material."""
    > def __init__(self):
    > ancestor.__init__(self)
    > thread_specific_storage = {}
    > thread_specific_storage_lock = thread.allocate_lock()
    > def check_and_start_daemon(self):
    > if not self.is_daemon_running():
    > self.start_daemon()

    [snip some code]
    > def start_daemon(self):
    > try:
    > first_pid = os.fork()
    > except OSError, e:
    > log_error("Failed to make first fork for daemon. Error: "
    > + \
    > e.strerror)
    > return
    > if first_pid == 0:
    > os.chdir("/")
    > os.setsid()
    > os.umask(066)
    > try:
    > second_pid = os.fork()
    > except OSError, e:
    > log_error("Failed to make second fork for daemon.
    > Error: " + \
    > e.strerror)
    > return
    > if second_pid == 0:
    > self.run_daemon()


    I believe the start_daemon routine may be your problem.

    First, you may want to look at this recipe in the online Python Cookbook:

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012

    I believe that's the recipe you're trying to follow in the paper copy;
    the online version, though, includes some useful comments about things
    like decoupling from stdin, stdout and stderr, which might cause
    problems if you don't do it.

    I'm noticing one omission here: the sys.exit(0) calls after the two
    forks. I understand not putting in a sys.exit(0) after the first fork,
    if you want your CGI script to continue running after forking off the
    daemon, but after the second fork, the parent should close. It might
    also be a good idea to split this out into two scripts:

    --- begin cgiscript.py ---
    def is_daemon_running():
    try:
    # Communicate with daemon via socket.
    return True
    except socket.error:
    return False

    def start_daemon():
    os.system('daemon.py parameters')

    def check_and_start_daemon():
    if not is_daemon_running():
    start_daemon()

    def do_work():
    check_and_start_daemon()
    # Whatever else needs to happen...
    ---- end cgiscript.py ----


    --- begin daemon.py ---
    def daemonize_self():
    def start_daemon(self):
    try:
    first_pid = os.fork()
    except OSError, e:
    log_error("Failed to make first fork for daemon. Error: " + \
    e.strerror)
    return
    if first_pid > 0:
    # Exit first parent
    sys.exit(0)
    else:
    os.chdir("/")
    os.setsid()
    os.umask(066)
    try:
    second_pid = os.fork()
    except OSError, e:
    log_error("Failed to make second fork for daemon. Error: " + \
    e.strerror)
    return
    if second_pid > 0:
    # Exit second parent
    sys.exit(0)
    else:
    # Optional but recommended: disconnect stdin, stdout, stderr
    new_stdin = file('/dev/null', 'r')
    new_stdout = file('/dev/null', 'a+')
    new_stderr = file('/dev/null', 'a+', 0)
    os.dup2(new_stdin.fileno(), sys.stdin.fileno())
    os.dup2(new_stdout.fileno(), sys.stdout.fileno())
    os.dup2(new_stderr.fileno(), sys.stderr.fileno())
    # Now we're ready
    run_daemon()

    def run_daemon():
    # Insert processing here
    ---- end daemon.py ----

    This FAQ might also be useful:

    http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16

    --
    Robin Munn <> | http://www.rmunn.com/ | PGP key 0x6AFB6838
    -----------------------------+-----------------------+----------------------
    "Remember, when it comes to commercial TV, the program is not the product.
    YOU are the product, and the advertiser is the customer." - Mark W. Schumann
    Robin Munn, Aug 1, 2003
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    315
  2. Professor Chen
    Replies:
    0
    Views:
    141
    Professor Chen
    Feb 6, 2006
  3. Rob Young

    forking and ending a CGI process

    Rob Young, Aug 11, 2003, in forum: Perl Misc
    Replies:
    1
    Views:
    116
    Gregory Toomey
    Aug 11, 2003
  4. Clyde Ingram
    Replies:
    1
    Views:
    442
    Randal L. Schwartz
    Dec 12, 2003
  5. Michael Smith

    Newbie needs help with forking

    Michael Smith, Oct 27, 2004, in forum: Perl Misc
    Replies:
    0
    Views:
    63
    Michael Smith
    Oct 27, 2004
Loading...

Share This Page