gpt4 book ai didi

windows - 全局信号量忽略本地信号量

转载 作者:可可西里 更新时间:2023-11-01 09:53:08 26 4
gpt4 key购买 nike

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

这里是旧代码:

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

所以我做了一些研究,了解了全局信号量并将代码更改为:

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 并尝试启动该应用程序,它不会运行(按预期)。

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

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

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

最佳答案

kernel object namespaces 的文档解释说:

For processes started under a client session, the system uses the session namespace by default.

由于旧程序未明确包含 namespace ,因此使用 session namespace Local\。这意味着旧程序创建了一个名为 Local\xxx 的信号量。现在,新程序使用名为 Global\xxx 的信号量。所以你有两个不同的信号量,程序完全没有意识到自己。

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

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

请注意,不可能将跨 session 排除反驳到现有程序中。他们已经在使用 Local\xxx 并且您现在无法更改它。

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

关于windows - 全局信号量忽略本地信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27226992/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com