Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

c++ - How to block running two instances of the same program?

I need to make sure that user can run only one instance of my program at a time.
Which means, that I have to check programatically, whether the same program is already running, and quit in such case.

The first thing that came to my mind was to create a file somewhere, when the program starts. Then, each other instance of the program would check for this file and exit if it found it.
The trouble is, that the program must always exit gracefully and be able to delete the file it created, for this to work. In case of, say, power outage, the lock file remains in place and the program can't be started again.

To solve this, I decided to store the first program's process ID into the lock file and when another instance starts, it checks if the PID from the file is attached to some running process.
If the file doesn't exist, is empty, or the PID doesn't correspond to any existing process, the program continues to run and writes its own PID to the file.

This seems to work quite fine - even after an unexpected shutdown, the chance that the (now obsolete) process ID will be associated with some other program, seems to be quite low.

But it still doesn't feel right (there is a chance of getting locked by some unrelated process) and working with process IDs seems to go beyond the standard C++ and probably isn't very portable either.

So, is there another (more clean and secure) way of doing this? Ideally one that would work with the ISO 98 C++ standard and on Windows and *nix alike.
If it cannot be done platform-independently, Linux/Unix is a priority for me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are several methods you can use to accomplish only allowing one instance of your application:

Method 1: Global synchronization object or memory

It's usually done by creating a named global mutex or event. If it is already created, then you know the program is already running.

For example in windows you could do:

    #define APPLICATION_INSTANCE_MUTEX_NAME "{BA49C45E-B29A-4359-A07C-51B65B5571AD}"

    //Make sure at most one instance of the tool is running
    HANDLE hMutexOneInstance(::CreateMutex( NULL, TRUE, APPLICATION_INSTANCE_MUTEX_NAME));
    bool bAlreadyRunning((::GetLastError() == ERROR_ALREADY_EXISTS));
    if (hMutexOneInstance == NULL || bAlreadyRunning)
    {
        if(hMutexOneInstance)
        {
            ::ReleaseMutex(hMutexOneInstance);
            ::CloseHandle(hMutexOneInstance);
        }
        throw std::exception("The application is already running");
    }

Method 2: Locking a file, second program can't open the file, so it's open

You could also exclusively open a file by locking it on application open. If the file is already exclusively opened, and your application cannot receive a file handle, then that means the program is already running. On windows you'd simply not specify sharing flags FILE_SHARE_WRITE on the file you're opening with CreateFile API. On linux you'd use flock.

Method 3: Search for process name:

You could enumerate the active processes and search for one with your process name.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...