Archive for March, 2010
Python Daemonize
Code copied from Xen.
def daemonize():
# Detach from TTY
# Become the group leader (already a child process)
os.setsid()
# Fork, this allows the group leader to exit,
# which means the child can never again regain control of the
# terminal
if os.fork():
os._exit(0)
# Detach from standard file descriptors, and redirect them to
# /dev/null or the log as appropriate.
# We open the log file first, so that we can diagnose a failure to do
# so _before_ we close stderr
try:
parent = os.path.dirname(XEND_DEBUG_LOG)
mkdir.parents(parent, stat.S_IRWXU)
fd = os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND, 0666)
except Exception, exn:
print >>sys.stderr, exn
print >>sys.stderr, ("Xend failed to open %s. Exiting!" %
XEND_DEBUG_LOG)
sys.exit(1)
os.close(0)
os.close(1)
os.close(2)
if XEND_DEBUG:
os.open('/dev/null', os.O_RDONLY)
os.dup(fd)
os.dup(fd)
else:
os.open('/dev/null', os.O_RDWR)
os.dup(0)
os.dup(fd)
os.close(fd)
print >>sys.stderr, ("Xend started at %s." %
time.asctime(time.localtime()))
See more about Process Group from Wiki.
A note from ‘man 2 setsid’
A child created via fork(2) inherits its parent’s session ID. The ssession ID is preserved across an execve(2).
A process group leader is a process with process group ID equal to its PID. In order to be sure that setsid() will succeed, fork(2) and _exit(2), and have the child do setsid().
配置ntp服务
虚拟机里面的时间不对,看着挺不爽的。所以简单配置了一个ntp服务,ntpd(8)的manpage写得很清楚了。
主要是把server填好,其他的我都没有管。
/etc/ntp.conf
server ntp.fudan.edu.cn
# ntpq -q
Python @staticmethod vs @classmethod
There are two predefined decorators in Python: @staticmethod and @classmethod.
I’m somewhat confused. For someone who has a shallow Java background, static method and class method are just the same.
See this for short.
And see Python PEP and manuals for details.
Borg Pattern in Python
During the search about Python singleton pattern, I discovered [ActiveState recipe 66531].
In this Borg Pattern, instances’ internal dictionary points to the same place, so all instances share the same state. Also, [Alex Martelli], the author of this recipe, has a interesting comment: Borg Pattern != Singleton Pattern. I admit that I confuse Borg Pattern with Singleton Pattern at first.
It’s NOT a singleton object… it doesn’t NEED to be! This is a completely and deeply different pattern from Singleton, and thus I find the latest comment totally off-base. Singleton focuses (wrongly) on object IDENTITY: that’s what the Gof4 focuses on, that’s what “EffC++” focuses on, etc, etc. But we don’t really care about identity most of the time, but about state and behavior.
The “Borg” design pattern IS quite possible in C++ (just a bit more laborious, but not much) and was indeed once written up in C++ Report (but I forget the name it was given then and can’t find my old issue): you get as many objects as you want, with separate identities but all sharing state and behavior. That’s the POINT! Just about all the practical USEFULNESS of Singleton without the troublesome identity-issue that Singleton tends to give.
Here’s the code, quite simple, cool.
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
Python Singleton Pattern Implementation
There are three ways to get this job done.
1 Module Implementation
The easiest implementation is to use a module scope variable. Module is persistent and shared by all references through its life time, no matter how it is renamed or modified.
See this [stackoverflow post on Python singleton]. Xen Xend makes use of this Python feature, which exposes a moudule function as interface to singleton class.
2 Class Implementation
The second implemention is class implementation, it’s not so convenient because Python does not support static variable itself. It certainly requires some tricks to get this job done.
According to this [ActiveState recipe 52558], it’s all about create exactly one instance of some class. But this is not so convient cause it uses automatic delegation.
3 Function Argument Default Value Implementation
Also another trick. The default value of a function argument is initialized only once and persistent. See the following example.
def f(x, l=[]):
l.append(x)
return l
This is least recommended.