15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Opening multiple instances of a 32bit app

Roger Lamb RAS+ 95 -- rasplus@lambsoftware.com
Thursday, January 11, 1996

I found a great KB article on the topic:

Title: SAMPLE: Limiting 32-bit Applications to a Single Instance 
Document Number: Q141752           Publ Date: 09-JAN-1996 
Product Name: Microsoft C Compiler 
Product Version: 4.00 
Operating System: WINDOWS NT

It works fine MOST of the time, but I found that if I fire off the app at
the same time, it seems that it consistentely possible to not detect the
Window Class that this method talks about and it will create more than one
instance.

I have very little control over starting up the apps so fast as it is being
called by Win95 from a dll (I think)... anyway.. it will fire off two
requests so fast that the both will fire up.

If one is aready running it works as expected.

Q: Is there another method (Memory file or shared memory) under the 32 bit
world that can be used to tell if more than one instance is running under
this fluke.  Or is there a workaround to this?

Looking for any leads!

Sincerely,
Roger C. Lamb Jr.

Lamb Software, Inc.
Email: rasplus@lambsoftware.com
Upates: http://www.lambsoftware.com




Doug Boone -- dboone@zeus.clr.com
Friday, January 12, 1996

[Mini-digest: 4 responses]

[Moderator's note: Gee, wouldn't it be nice if this were just part
of the system, or at least part of MFC?]

>Q: Is there another method (Memory file or shared memory) under the 32 bit
>world that can be used to tell if more than one instance is running under
>this fluke.  Or is there a workaround to this?
  
Thats what I do, have each InitApplication() create a semaphore. If
GetLastError() returns ERROR_ALREADY_EXISTS then I know that some other
application is already running and has gotten that far so I bail.

-----From: Mario Contestabile 

Yourapp::InitInstance()
{
hMutexOneInstance = CreateMutex(NULL,TRUE,_T("PreventSecondInstance"));

if(GetLastError() == ERROR_ALREADY_EXISTS)
 bFound = TRUE;

if(hMutexOneInstance) ReleaseMutex(hMutexOneInstance);

return (bFound == TRUE) ? FALSE : TRUE;
}

mcontest@universal.com

-----From: "Aravind Balakrishnan(abalakri@us.oracle.com)" 

There is a nice section in Jeffrey Richter's book Advanced Windows NT about 
this.  Essentially, it uses shared data segments between processes. 
 
Step1: 
===== 
In your main file, have: 
#pragma data_seg(".SharedData") 
 
LONG nUsageCount = -1; 
 
#pragma data_seg() 
 
Step 2 : 
======= 
In your Application's InitInstance(), call: 
InterlockedIncrement ( &nUsageCount ); 
 
This function returns the incremented value of the variable.  If it is 
non-zero, you know that you are not the first App. 
 
In your Application's ExitInstance() call: 
InterlockedDecrement( &nUsageCount ); 
 
Step3: 
==== 
In your DEF file, have the following lines:  Note that the segment name you 
give here should match the one in the application's main file. 
 
SEGMENTS 
	.SharedData shared 
 
I am using this in our application on NT.  I have not checked it on Win95, 
although I believe it should work there also. 
 
Hope this helps! 
 
 
 
Cheers,   
Aravind.   
===   
 
Aravind Balakrishnan  
Systems Management Products, Oracle Corp. 
(415)506-0432 
 
-----From: Niels Ull Jacobsen 

You'd better use one of the built-in synchronisation methods.
See Q124134 : Allowing Only One Application Instance on Win32s for a sample
of using a memory mapped file for synchronisation.

It doesn't include starting the previous instance, but if you detect
that you're not the only one running, it should be pretty simple:

if CreateFileMapping fails, try to find the previous instance from the
window class name. If it's not found, sleep for a while and start over
(with CreateFileMapping).

In this way, either you will find the other instance when it gets
around to creating it's window or CreateFileMapping will eventually succeed.

The advantage of using CreateFileMapping instead of CreateObject is
that it also works on Win32s.

--
Niels Ull Jacobsen, Kruger A/S

Everything stated herein is THE OFFICIAL POLICY of the entire Kruger
group and should be taken as legally binding in every respect. Pigs
will grow wings and fly.



Doug Boone -- dboone@zeus.clr.com
Saturday, January 13, 1996

At 10:33 AM 1/12/96 -0600, you wrote:
>[Mini-digest: 4 responses]
>
>[Moderator's note: Gee, wouldn't it be nice if this were just part
>of the system, or at least part of MFC?]
  
I guess the next question is, which is more efficient/fastest/uses least
resources: Using a mutex, a semaphore, a memory-mapped file or a variable in
a named data segment.
 
My understanding is that Semaphores are real cheap as long as no one is
waiting on them. The second user that has to wait causes a Ring transition
but otherwise they're just set and released. 

In "Fundamentals of Great Server Applications" by Mark Lukovsky one of the
slides said "Used internally by Windows NT in critical section objects (when
contention occurs), and in some queuing cases to track the number of items
in a list."  (Windows NT Server PDC 1995) I guess that's where I got that
impression but I don't find any real documentation about the relative
overhead of each signaling system except that CriticalSections are cheapest
because they only exist within a single process.
 
I guess this isn't really MFC related, except that writing a class that
would provide a standard method of solving the problem would be trivial as
long as you know what the relative advantages of each method are.





| Вернуться в корень Архива |