On Fri, 23 Feb 2007 23:39:03 +0100, Troy Melhase <[EMAIL PROTECTED]>  
wrote:

>> The first time A starts, it should open a B process and start
>> communicating with it. All other times an A instance starts it should
>> simply talk with the B that already is open.
>
> B should write its process id to a location known by both
> applications.  When A starts, it should read that PID from the file
> and attempt to communicate with the process having that PID.
>
> When B starts, it should also check for the file.  If it's found and
> if the PID in it is present in the process table, then B should exit.
> Otherwise, it should start normally and write its own PID to the file.

You have a race condition here: if another instance of B is created  
between the check and the creation of the file, you'll have two instances  
running. And remember Murphy's law: yes, it will happen, and quicker than  
you can imagine ;-)

To prevent this from happening, I usually create a special directory for  
the PID file, and I delete both the file and the directory when the  
process exits. The advantage is that os.mkdir is basically a "test and  
set" in a single operation: if two of these are attempted at "the same  
time", only one can succeed. It is also cross-platform and even works on  
shared file systems.

So the code would be something like:

## Try to create directory
try:
   os.mkdir(os.path.join(common_directory, "B_lock"))
except OSError:
   ## Failed: another instance is running
   sys.exit()
## Create the PID file
# (...)
try:
   ## Application code
   # (...)
finally:
   ## Remove the PID file
   # (...)
   ## Delete directory
   os.rmdir(os.path.join(common_directory, "B_lock"))

HTH
-- 
python -c "print ''.join([chr(154 - ord(c)) for c in  
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to