Having multiple instances of a single application start a singleinstance of another one

B

buffinator

I have two applications that should work together, let's call them A and B.

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.

The problem here is, if I start say 40 A applications at once... how do
I check if a B is open "fast enough" so that the other A's (not the
first one) won't spawn new B's?

Im programming this in windows and am currently using the horrible
solution in A

if not win32gui.FindWindow(None, "Name of B"):
spawn_B_here()

This only works well if there is a small time between the A's started
first...

What would the best solution for my problem be?

/buffis
 
T

Troy Melhase

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.
 
B

buffinator

Troy said:
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.

Three very simple questions then.

1. How do I find out a running applications process ID

2. How do I check if a process ID is bound to a running application.

3. There won't be any issues with different applications trying to read
and write the same file doing this?

/buffis
 
T

Troy Melhase

Three very simple questions then.
1. How do I find out a running applications process ID

import os
mypid = os.getpid()
2. How do I check if a process ID is bound to a running application.

this is os-specific. i'm sure there's a windows api provided for it.
3. There won't be any issues with different applications trying to read
and write the same file doing this?

shouldn't be any problem: only the first app started will write to the file.
 
J

Jerry Hill

2. How do I check if a process ID is bound to a running application.

Under windows, this should work:(0, 4, 1048, 1496, 1656, 1836, 1896, 756, 988, 1712, 220, 1156, 240,
1600, 1932, 428, 1100, 1880, 1152, 1444, 296, 624, 536, 412, 1812,
3384, 2064, 2164, 2344, 2516, 2816, 2992, 3412, 3628, 2836, 3168,
3420, 3408, 816, 1676, 504, 3244, 2404, 452, 1624, 3924, 2660, 3736,
3608, 1304)
 
L

Larry Bates

buffinator said:
I have two applications that should work together, let's call them A and B.

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.

The problem here is, if I start say 40 A applications at once... how do
I check if a B is open "fast enough" so that the other A's (not the
first one) won't spawn new B's?

Im programming this in windows and am currently using the horrible
solution in A

if not win32gui.FindWindow(None, "Name of B"):
spawn_B_here()

This only works well if there is a small time between the A's started
first...

What would the best solution for my problem be?

/buffis

Others have answered your specific question on the forum, I thought
I would make a suggestion. You should consider writing application B
as a Windows Service that gets started once (maybe even auto start
when the machine boots) and runs forever in the background. Then have
all your A's bind to it and communication (via sockets, pipes, filesystem,
database, ...). That way your A's won't have the problem you describe.

Just a suggestion.

-Larry
 
D

Dennis Lee Bieber

3. There won't be any issues with different applications trying to read
and write the same file doing this?
Reading shouldn't be a problem -- except for the short period when
the file is there but empty (so put a try/except in a loop with the
except having a timed delay).

The create/write MAY have a possibility...

B1 B2
attempt read
not found attempt read
create not found
write PID1 create
close write PID2
close

so I'd suggest a short delay be performed after the close followed by

attempt read
found PID2 attempt read
exit this version found PID2
continue
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
E

Eric Brunel

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top