Difference between revisions of "Fork.py"

From PeformIQ Upgrade
Jump to navigation Jump to search
 
(One intermediate revision by the same user not shown)
Line 2: Line 2:
#!/usr/bin/env python
#!/usr/bin/env python
#
#
Purpoe: Check functionn of fork under cygwin
Purpose: Check function of fork() with cygwin
#
#
#  $Id: fork2.py,v 1.1.1.1 2003/10/22 13:05:22 zyx Exp $
#  $Id: fork2.py,v 1.1.1.1 2003/10/22 13:05:22 zyx Exp $
Line 11: Line 11:
   More complex fork framework
   More complex fork framework


   fork and in the child use setsid() and other calls to detach
   fork() and in the child use setsid() and other calls to detach
   from the controllling terminal
   from the controllling terminal
"""
"""
Line 374: Line 374:


[[Category:Python]]
[[Category:Python]]
[[Category:Examples]]

Latest revision as of 16:07, 19 July 2009

#!/usr/bin/env python
#
#  Purpose: Check function of fork() with cygwin
#
#  $Id: fork2.py,v 1.1.1.1 2003/10/22 13:05:22 zyx Exp $
#
#---------------------------------------------------------------------

"""
  More complex fork framework

  fork() and in the child use setsid() and other calls to detach
  from the controllling terminal
"""

#---------------------------------------------------------------------

import getopt
import os
import sys
import signal
import time
import logging
import whrandom

#---------------------------------------------------------------------

__id__        = "@(#) fork2.py  [1.0.0] 14/10/2003"
__version__   = "1.0.0"

TRUE          =  1
FALSE         =  0

LOGFILE      = "fork2.log"
PIDFILE      = "fork2.pid"

daemonFlg     =  0
debugFlg      =  0
silentFlg     =  0
verboseFlg    =  0
waitFlg       =  0
inParent      =  0

pause         =  2
duration      = 10
noSessions    = 10

#=====================================================================

def now(): 
   return time.ctime(time.time())       # current time on the server

#---------------------------------------------------------------------

def shutdown():
   log.info("[fork2]  Suttting down")

   if inParent:
      os.unlink(PIDFILE)

   sys.exit(99)

#---------------------------------------------------------------------

def sigTerm(signum, frame):
   "SIGTERM handler"

   s = "[fork2]  Caught SIGTERM!"
   print s
   log.info(s)

   shutdown()

#---------------------------------------------------------------------

def readConfig():
   pass

#---------------------------------------------------------------------

def checkRunning():
   try:
      pfp = open(PIDFILE, 'r')
   except IOError, e:
      pfp = 0

   if pfp:
      line = pfp.readline()
      line = line.strip()

      serverPid   = int(line)

      noProcess    = 0

      try:
         os.kill(serverPid, 0)
      except OSError, e:
         if e.errno == 3:
            noProcess = 1
         else:
            print "kill() failed with errno %d" % e.errno
            sys.exit(0)

      if noProcess:
         print "[fork2]  Stale server pid file!"
         pfp.close()
         os.unlink(PIDFILE)

         return 0
      else:
         pfp.close()
         return serverPid

      return serverPid
   else:
      return 0

#---------------------------------------------------------------------

def writePidfile(pid):
   try:
      pfp = open(PIDFILE, 'w')
   except IOError, e:
      print "[fork2]  Could not open %s" % PIDFILE
      sys.exit(0)

   print >>pfp, "%d" % pid

   pfp.close()

   return pid

#---------------------------------------------------------------------

def becomeDaemon():
   pid = os.fork()

   if pid == 0:     # In child
      print "[fork2]  fork() -> 0 (%d)" % getpid()
      time.sleep(1)
      pass
   elif pid == -1:  # Error
      print "[fork2]  fork() failed!"
      time.sleep(1)
      sys.exit(0)
   else:            # In parent
      print "[fork2]  fork() ->", getpid()
      time.sleep(1)
      sys.exit(0)

   time.sleep(2)

   os.setsid()

   pid = os.getpid()

   return pid

#---------------------------------------------------------------------

def init():
   global ctrlPid

   ctrlPid = checkRunning()

   if ctrlPid:
      print "[fork2]  Server already running! (pid = %d)" % ctrlPid
      sys.exit(0)

   if daemonFlg:
      ctrlPid = becomeDaemon()
   else:
      ctrlPid = os.getpid()

   writePidfile(ctrlPid)

   global log

   log  = logging.getLogger('fork2')
   hdlr = logging.FileHandler(LOGFILE)
   fmtr = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

   hdlr.setFormatter(fmtr)
   log.addHandler(hdlr) 
   log.setLevel(logging.INFO)

   log.info("Server started processing")

   global uname

   readConfig()

   if (not silentFlg):
      print "[fork2]  Server pid is %d" % ctrlPid

   signal.signal(signal.SIGTERM, sigTerm)

#---------------------------------------------------------------------

def terminate():
   serverPid = checkRunning()

   if serverPid:
      if (not silentFlg):
         print "[fork2]  Terminating server with pid, %d\n" % serverPid

      os.kill(serverPid, signal.SIGTERM)

      if (waitFlg):
         while 1:
            try:
               kill(serverPid, 0)
            except OSError, e:
               if e.errno == 3:
                  break
               else:
                  print "[server:terminate]  kill() failed with errno %d" % e.errno
                  sys.exit(0)
 
            time.sleep(1)

   return 0

#=====================================================================

def doChild(no):
   global inParent

   inParent = 0

   toGo = float(duration + 10)

   #os.setsid()

   pid = os.getpid()

   signal.signal(signal.SIGTERM, sigTerm)

   while toGo > 0.0:
      t     = whrandom.randint(1, 1000) * 0.001

      toGo -= t
      time.sleep(t)
      s = "[fork2]  In child %3d [%d] - %5.2f" % (no, pid, t)
      log.info(s)
      print s

#---------------------------------------------------------------------

def spawn():
   global inParent

   inParent = 1

   pids = {}

   for i in range(noSessions):
      pid = os.fork()

      if pid == 0:     # In child
         doChild(i)
      elif pid == -1:  # Error
         print "[fork2]  fork() failed!"
         time.sleep(2)

         sys.exit(0)
      else:            # In parent
         pids[i]   = pid

   myPid = os.getpid()

   print "[fork2]  In parent [%d]: fork() -> %d" % (myPid, pid)
   print "[fork2]  In parent [%d]: waiting..." % myPid

   time.sleep(duration)

   print "[fork2]  *** In parent [%d]: Applying SIGTERM" % myPid

   for i in range(noSessions):
      os.kill(pids[i], signal.SIGTERM)

   while 1:
      try:
         (pid, status) = os.wait()
      except OSError, e:
         if e.errno == 10:  # No children
            break

      print "[fork2]  In parent - wait() --> (PID %d, Status %d, Signal %d)" % \
           (pid, ((status & 0xff00)>>8), (status & 0xff))

      i -= 1

   return 0

#---------------------------------------------------------------------

def main():
   global debugFlg
   global verboseFlg
   global waitFlg
   global duration
   global noSessions

   try:
      opts, args = getopt.getopt(sys.argv[1:], "dD:n:TvVw?")
   except getopt.error, e:
      print __doc__
      return 1

   wrk  = os.getcwd()
   base = os.path.basename(wrk)

   for o, a in opts:
      if o == '-d':
         debugFlg      = 1
      elif o == '-D':
         duration      = int(a)
      elif o == '-n':
         noSessons     = int(a)
      elif o == '-T':
         terminate()
         return 0
      elif o == '-v':
         verboseFlg    = 1
      elif o == '-V':
         print "[fork2]  Version: %s" % __version__
         return 1
      elif o == '-w':
         waitFlg       = 1
      elif o == '-?':
         print __doc__
         return 1

   print "[fork2]  Working directory is %s" % os.getcwd()

   if args:
      for arg in args:
         print arg

   init()

   spawn()

#---------------------------------------------------------------------

if __name__ == '__main__' or __name__ == sys.argv[0]:
   try:
      sys.exit(main())
   except KeyboardInterrupt, e:
      s = "[fork2]  Interrupted!"
      print s
      log.info(s)
      shutdown()

#---------------------------------------------------------------------

"""
Revision History:

     Date     Who   Description
   --------   ---   --------------------------------------------------
   20031018   plh   Initial implementation

Problems to fix:

To Do:

Issues:

"""