概述
在win平台下,如果要多进程共享访问同一把互斥,则使用有名CreateMutex或者有名CreateFileMapping。
例如:
HANDLE mutex = CreateMutexA(NULL, false, "MyMutexName");
使用上面的代码在同一个用户、同一个session下是没有问题的,但是以不同用户或者同一用户不同session时(比如在windows server中运行程序,使用远程桌面登录时,不同的远程桌面终端的MutexName是不同的),此mutex就不是同一个了。
因为不同用户或者session中实际生成的MutexName就有一个前缀,类似:
\session\1\basenamedobjs\MyMutexName
\session\9\basenamedobjs\MyMutexName
解决方案
此时如果希望不同的用户访问的是同一把锁,同一块共享内存,则需要在名称前加"Global",比如:
HANDLE mutex = CreateMutexA(NULL, false, "Global\\MyMutexName");
但是只做上一步是不完整的,因为不同的用户的权限不一样,使用OpenMutex时会提示无权限访问,此时就需要在CreateMutex时设置安全权限。
示例代码如下,在示例代码中创建了一个空的DACL,表示所有人都可以访问这块共享内存或者锁,暂时没有仔细研究精细控制权限:
code 1:
SECURITY_ATTRIBUTES sa = { sizeof(sa) };
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
sa.lpSecurityDescriptor = &sd;
HANDLE mutex = CreateMutexA(&sa, 0, "Global\\MyMutexName");
code2:
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = &sd;
CreateFileMapping(.., &sa,...);