在Windows环境中,我不希望我的程序的两个实例同时运行。
相关
Is using a Mutex to prevent multiple instances of the same program from running safe?
答案 0 :(得分:10)
我认为你需要在前进之前考虑一下你的情景。不止一次对“运行相同程序”有许多不同的解释。比如你
所有这些都有不同的,虽然相似的解决方案。
最容易描述的是每台机器。在这种情况下,您想要创建一个名为Mutex。一个启动每个程序必须获得这个互斥锁,如果它们成功,它们会在进程生命周期内运行并持有互斥锁。否则其他一些程序正在运行,它们会立即退出。
不幸的是,这种方法也有其缺点。如果我想弄乱你的程序,我可以创建一个具有相同名称的互斥锁。这将阻止您的程序运行任何实例,因为他们无法分辨谁拥有互斥锁,只是某些东西持有互斥锁。
答案 1 :(得分:9)
您可以在应用程序的第一个实例启动时创建互斥锁。要防止第二个实例,您需要做的就是检查是否正在使用互斥锁。
实际上有一个问题是关于为此目的使用互斥量here查看JaredPar的答案。
注意:如果您希望“一个实例”仅应用于用户的会话(而不是所有用户),则可以使用本地互斥锁
答案 2 :(得分:7)
如果是您的程序,那么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 ...
}
如果您只需要一个简单的检查,就不需要疯狂复杂......
答案 3 :(得分:3)
最好的方法是使用互斥锁。见Using Mutex Objects。
答案 4 :(得分:3)
另一种简单的解决方案是创建一个适当唯一的全局命名事件(可能是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;
}
}
答案 5 :(得分:2)
这是我使用boost.interrprocess编写的脚本,我用它在GUI和CLI版本之间进行同步。
您可能会发现它很有用:
#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)
{
...
}
因此您可以轻松地并行限制多少个进程。
答案 6 :(得分:2)
使用Qt时,您可以下载QtSingleApplication组件。
答案 7 :(得分:1)
正如其他人所建议的那样使用互斥锁。
来自MS的CreateMutex() documentation有很多有用的信息,并且特别针对使用互斥锁来防止多个程序实例运行的情况。特别是:
CreateMutex()
致电bInitialOwner = FALSE
,然后调用等待函数(例如WaitForSingleObject()
)以确保只有一个实例获取互斥锁。答案 8 :(得分:0)
在程序启动时,您可以enumerate the processes running on your machine
然后,如果您发现自己已经在运行,请退出
答案 9 :(得分:-1)
您可以检查窗口类是否已注册。请查看this MSDN条目。