Difference between revisions of "Fork.py"
Jump to navigation
Jump to search
PeterHarding (talk | contribs) |
PeterHarding (talk | contribs) |
||
| Line 2: | Line 2: | ||
#!/usr/bin/env python | #!/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 $ | # $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 | ||
""" | """ | ||
Revision as of 13:21, 30 March 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:
"""