首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >全局信号量忽略本地信号量

全局信号量忽略本地信号量
EN

Stack Overflow用户
提问于 2014-12-01 11:03:42
回答 1查看 593关注 0票数 2

我有一个访问某些文件和系统资源的应用程序,所以可能只有一个应用程序活动实例。这是通过创建一个命名的信号量并在已经分配了信号量时停止应用程序运行来实现的。在过去(阅读:当Windows是最常见的操作系统),但现在我们注意到旧代码不适用于多个用户会话。

在这里,旧代码:

代码语言:javascript
复制
hInstanceSem := CreateSemaphore(nil, 0, 1, PChar(GetProductName(Application.ExeName)));
if (hInstanceSem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then
// do not run the Application

因此,我做了一些研究,了解了全局信号量,并将代码修改为:

代码语言:javascript
复制
function CreateGlobalSemaphor(SemaphorName: String): Cardinal;
var
  desc: SECURITY_DESCRIPTOR;
  att : TSecurityAttributes;
  sem : Cardinal;
begin
  att.nLength := SizeOf(TSecurityAttributes);
  att.bInheritHandle := true;
  att.lpSecurityDescriptor := @desc;

  InitializeSecurityDescriptor(att.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(att.lpSecurityDescriptor, True, nil, False);

  sem := CreateSemaphore(@att, 0, 1, PChar('Global\' + SemaphorName));
  if (sem <> 0) and (GetLastError() <> ERROR_ALREADY_EXISTS) then begin
    Result := sem;
  end else begin
    Result := 0;
    CloseHandle(sem);
  end;
end;

if CreateGlobalSemaphor(GetProductName(Application.ExeName)) = 0 then
// do not run the Application

现在,当我在User1上启动应用程序时,更改为User2并尝试启动应用程序,它将不会运行(按预期运行)。

但是,当我运行一个较旧版本的程序,并在同一个用户会话中使用新代码启动当前版本时,新代码将忽略由旧代码创建的信号量,并启动我的应用程序的第二个实例。(不用说它崩溃了.)

在我看来,本地信号量超出了全局信号量的范围,否则无法创建同名的第二个对象。我的问题是:全局信号量(新代码)如何检测到已经分配了同名的本地信号量(旧代码)?

请记住,这是一个向后兼容性问题。我不能简单地重新编译和重新分发我的应用程序的旧版本。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-01 12:21:43

kernel object namespaces的文档解释说:

对于在客户端会话下启动的进程,系统默认使用会话命名空间。

由于旧程序没有显式地包含名称空间,所以使用了Local\。这意味着旧程序创建一个名为Local\xxx的信号量。现在,新程序使用了一个名为Global\xxx的信号量。因此,您有两个不同的信号量和程序完全不知道自己。

  • 如果希望新程序与旧程序交互,则必须使用名为Local\xxx的对象。
  • 如果希望新程序在不同的会话中阻止其他新程序,则必须使用名为Global\xxx的对象。

这里得出的明显结论是,您需要创建两个对象。一个名为Local\xxx,另一个命名为Global\xxx

请注意,不可能将交叉会话排除移植到现有程序中。他们已经使用了Local\xxx,您现在无法改变这种情况。

还必须修复新代码中的错误处理。您调用CreateSemaphore,然后继续调用GetLastError,而不首先检查调用CreateSemaphore返回的值。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27226992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档