Windows下C++防止进程多开

1. 概念

防止进程多开,一般是特指防止同一个exe进程重复打开。为什么要防止进程多开呢?

  1. 功能设计上不让用户打开两次,如各种游戏客户端。
  2. 防止多进程对资源访问的冲突。如当前进程对某文件可能在进行写读操作,再打开新进程时可能的写读操作会导致出现文件访问异常甚至崩溃。

2. 方法

网上很多资料推荐利用遍历窗口来判断,如果找到对应的窗口则认为进程已经打开。这种方法其实存在很大的风险。

  1. 窗口创建的过程中可能因为系统消息阻塞导致创建很慢,那么在窗口创建过程中再打开进程,并通过遍历窗口来判断则可能失败。
  2. 窗口关闭过程中,窗口销毁了,但是此时主进程以及其他子进程可能由于某些原因(如内存申请较大,释放较慢等)导致销毁较慢。在此过程中,再次打开进程,并通过遍历窗口来判断则可能失败。
    推荐用以下两种方法:

2.1. 通过互斥内核对象

所有的内核对象都是可以跨进程通信的,在此选择简单的内核对象互斥量。为了保证互斥量尽量延后释放,不建议使用手动调用ReleaseMutex来释放互斥量对象。操作系统的内核管理器会在进程销毁后自动释放所有的内核对象。

BOOL CXXXApp::InitInstance()
{
	HANDLE hObject = ::CreateMutex(NULL,FALSE, _T("MutexDemo"));  
	if(GetLastError() == ERROR_ALREADY_EXISTS)  
	{  
		return FALSE;  
	}
  ......

2.2. 通过共享内存段

除了内核对象外,我们还可以通过编译链接期间指定共享内存段来达到防止进程多开。此方式相比内核对象可能更可靠,因为内存段的回收是系统管理的,应该是在进程完全销毁了之后才回收清空的。

  • 申请共享内存段,段名需要保证唯一性
#pragma data_seg("MutexDemo")
int g_nOnlyOne = 0;
#pragma data_seg()
#pragma comment(linker, "/Section:MutexDemo,RWS")
  • 通过内存段变量进行判断
BOOL CTestFWApp::InitInstance()
{
	if (1 == g_nOnlyOne)
	{
		return FALSE;
	}
	g_nOnlyOne = 1;
  .......
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值