Single Instance of App only works when debugging (Mutex Problem) C++

Hi,

The following code works fine when debugging, only one instance of the application is started. However, when I build a release version of the code multiple instance of the app are allowed to run. ie MutexCreated is always returned as true.

I have tried all combinations of InitalOwner and Testing both MutexCreated and trying to lock the mutex following its creation. All work exactly as I would expect on a debug build but when switching to a release build all instances of the app will get the mutex lock.

Help/ advice please!!

Andrew

int main(array<System::String ^> ^args)

{

bool InitalOwner=true;

bool MutexCreated=false;

Mutex^ Mut = gcnew Mutex(InitialOwner,"Global\\MyAppMutex",MutexCreated);

if ( MutexCreated==true ) // Also tried if ( Mut->WaitOne(10,false) )

{

// Enabling Windows XP visual effects before any controls are created

Application::EnableVisualStyles();

// Create the main window and run it

Application::Run(gcnew Form1());

}

else

{

MessageBox::Show("Application is already running.","My App");

}

return 0;

}



Answer this question

Single Instance of App only works when debugging (Mutex Problem) C++

  • Asen Asenov

    Using WinObj The mutex does not appear in the BaseNamedObject list for the release build. (The mutex created flag in the code is however set to true) This explains why the app always thinks its the first instance.

    The mutex appears in the BaseNamedObject list for the debug build and handles are incremented correctly.

    I have created a new windows.forms app to test the mutex it works fine.

    A thought - This app started its life as a Visual C++ Express app a couple of months before VS2005 was released. As soon as VS2005 was released all development was switched to it. Could there be a compile/link time option introduced by Express that is now confusing the code in some way

    I realise that commenting out the app.run should not make the problem go away but it does. The App introduces various new namespaces could these be effecting the domain of the mutext

    As for cleaning up the mutex - I have assumed that garbage collection would tidy it up. It does appear to do so for the test app. (ie the mutex disappears from the BaseNamedObjects list when the last app closes.)


  • KeFei Wang

    The mutex works properly for me. Are you using separate user accounts to run the differing programs under

    Michael Taylor - 3/1/06


  • Target Su.

    Ok, tried that it works fine for both debug and release versions.

    I have also found the if I replace the line

    Application::Run(gcnew Form1());

    with

    while(true) {int x=0;x++;}

    The app now works as expected when compiled for both debug and release. ( it is a bit dull to watch though!)

    It appears there is something about the release version of the libraries or the release options that I am using that is confusing the mutex.

    Help still stuck!


  • Scott1978

    Just so Andrew doesn't think he is the only one that encountered this problem, I thought I would mention that I am having the same experience in a C# program built with VS 2005. The debug version works correctly, but the released version creates the mutex every time, even if it already exists.


  • Vanni Torelli

    I agree thanks for you time.

    Andrew


  • David Schulze

    No - All are being run under the same user account.

    It fails if each instance is run from the desktop or by starting multiple instances from within Visual Studio.

    Other than checking for instances of the process running, which will only work if the user has admin priviledges can anyone think of another approach


  • tbrauer

    There's no switch I'm aware of that should cause the problem you're seeing. Nevertheless I guess if you somehow managed to get it to use the single-threaded CRT it might have a problem but this shouldn't even be a problem. Maybe there is a problem with it trying to load the wrong binaries or something. Nevertheless I'd just transfer all your classes over to the new project and be done with it. Debugging problems with beta software just isn't worth the effort if you can work around it in my opinion.

    Michael Taylor - 3/2/06


  • tonyr1977

    I found another thread that explains the cause of this problem. The mutex is getting GC'd in the release build. Need to add a GC.KeepAlive(mutex) at the end of the program to tell the GCer to leave it active.
  • chachu207

    Ok, it's time to get nasty. Something is definitely not right. You aren't manipulating the mutex anywhere else in your code are you (say the form)

    Try this:

    1) Start the first instance of your app outside the debugger.

    2) Run winobj from SysInternals (http://www.sysinternals.com/Utilities/WinObj.html)

    3) Under BaseNamedObjects you should see your mutex. The handle count should be 1.

    4) Start another instance of your app. Check the handle count again. The handle count should be 2 because each app has a reference to the mutex.

    Note that commenting out the Application.Run call shouldn't have had any impact since the second instance should never even get into the loop. Also note that a mutex is a disposable object so you should be sure to clean it up before your app exits. Otherwise it is possible for you to orphan a global system object which wouldn't be good.

    Michael Taylor - 3/2/06


  • jesc

    Using mutexes and other named sync objects is standard practice for detecting multiple instances of an app. It is done all the time and I've personally done it on more than one occasion both inside .NET and out. Therefore there has to be something not quite right with your code.

    Take the following code and drop it into a C++ console app and verify it works under the circumstances you have.

    #include "stdafx.h"

    using namespace System;

    using namespace System::Threading;

    int main(array<System::String ^> ^args)

    {

    bool created = false;

    Mutex^ mutex = gcnew Mutex(true, "Global\\TestMutex", created);

    if (created)

    Console::WriteLine("Created mutex.");

    else

    Console::WriteLine("Mutex already exists.");

    Console::ReadLine();

    return 0;

    }

    Michael Taylor - 3/1/06


  • Single Instance of App only works when debugging (Mutex Problem) C++