在Windows环境下,我不希望同时运行两个程序实例。
相关
在Windows环境下,我不希望同时运行两个程序实例。
相关
如果这是你的程序,那么在 Windows 系统下最短的可能版本是:
int main(int argc, char** argv)
{
CreateMutexA(0, FALSE, "Local\\$myprogram$"); // try to create a named mutex
if(GetLastError() == ERROR_ALREADY_EXISTS) // did the mutex already exist?
return -1; // quit; mutex is released automatically
// ... program code ...
}
不需要变得过于复杂,如果您只需要一个简单的检查...
在继续之前,我认为你需要考虑一下你的情景。对于“多次运行相同程序”,有许多不同的解释。例如,您是希望:
这些都有不同但类似的解决方案。
最容易描述的是每台计算机仅运行一次的情况。在这种情况下,您需要创建一个命名的Mutex。每次启动程序时,它必须获取此mutex。如果成功获取,程序将运行并在进程生命周期内保持该mutex。否则,其他程序正在运行,它们会立即退出。
不幸的是,这种方法也有其缺点。如果我想破坏您的程序,我可以创建一个具有相同名称的mutex。这将防止您的程序运行任何实例,因为它们无法确定谁拥有该mutex,只知道有某个程序正在持有该mutex。
另一种简单的解决方案是创建一个适当唯一的全局命名事件(可能是 GUID 字符串),然后在启动时检查其是否存在。如果存在,则已经启动了该应用程序的一个实例。如果不存在,则自动创建该事件并可以继续运行,例如:
// for brevity, a complete set of error handling has been omitted
m_hEvent = CreateEvent(NULL, TRUE, FALSE, szMyUniqueNamedEvent);
switch (GetLastError)
{
// app is already running
case ERROR_ALREADY_EXISTS:
{
CloseHandle(m_hEvent);
// now exit
break;
}
// this is the first instance of the app
case ERROR_SUCCESS:
{
// global event created and new instance of app is running,
// continue on, don't forget to clean up m_hEvent on exit
break;
}
}
#pragma once
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
using boost::interprocess::windows_shared_memory;
using boost::interprocess::mapped_region;
using boost::interprocess::open_or_create;
using boost::interprocess::read_write;
using boost::interprocess::interprocess_exception;
class CProcessMutex
{
public:
CProcessMutex()
: m_region()
, m_status(false)
{
initSharedMemory();
Increment();
}
~CProcessMutex()
{
Decrease();
}
public:
int GetCount()
{
return m_status ? *(static_cast<unsigned char*>(m_region.get_address())) : 0;
}
private:
void initSharedMemory()
{
try
{
//Create a native windows shared memory object.
windows_shared_memory shm (open_or_create, "shared_memory", read_write, 1);
//Map the whole shared memory in this process
m_region.swap(mapped_region(shm, read_write));
m_status = true;
}
catch(interprocess_exception &ex)
{
ex.what();
m_status = false;
}
}
void Increment()
{
if(m_status) (*(static_cast<unsigned char*>(m_region.get_address())))++;
}
void Decrease()
{
if(m_status) (*(static_cast<unsigned char*>(m_region.get_address())))--;
}
private:
mapped_region m_region;
bool m_status;
};
CProcessMutex pm;
size_t current_process_count = pm.GetCount();
if(current_process_count > 1)
{
...
}
使用互斥锁,就像其他人建议的那样。
来自微软的CreateMutex()文档提供了许多有用的信息,并特别解决了使用互斥锁防止程序运行多个实例的情况。尤其是:
CreateMutex()
并设置 bInitialOwner = FALSE
,然后调用等待函数(例如WaitForSingleObject()
),以确保只有一个实例获取互斥锁。