我假设一旦进程创建了信号量,任何进程/用户都可以访问它。
是否可以对特定信号量设置访问限制,以便仅某些进程/用户可以访问该信号量,或者只有某些进程可以释放该信号量。
如果我们让信号量可供所有进程访问,我会发现一些问题。例如:虚拟进程可以读取信号量并随意释放锁,向真正等待信号量锁的实际进程发出错误信号。
所有这些问题都是因为我通过以下代码片段得到非常奇怪的输出而出现的:
use Win32::Semaphore;
$sem = Win32::Semaphore->new(0, 1,"reliance2692")
or print "Can't create semaphore\n";
$sem = Win32::Semaphore->open("reliance2692")
or print "Can't open semaphore\n";
print "Semaphore:" . $sem . "\n";
通过运行上面的程序,我得到以下输出
Can't create semaphore Can't open semaphore
输出显示创建信号量失败,甚至打开信号量失败。 如果具有给定名称的信号量已存在,则创建信号量可能会失败。 我不明白为什么打开信号量失败。
能否澄清一下创建信号量和打开信号量都失败的情况。
最佳答案
Win32::Semaphore->new
调用 Windows API 函数 CreateSemaphore
并获取进程的默认安全描述符,这通常意味着以与脚本相同的用户身份运行的进程可以拥有完全访问权限,而以其他帐户运行的进程则没有访问权限。所以,对于初学者来说,你的假设是错误的。
您在 Perl 代码中选择的名称将直接传递给 API 函数,因此它受相同的 namespace rules 约束。与所有其他 Win32 内核对象一样。
Win32::Semaphore 没有提供用于指定访问限制的接口(interface)。即使提供了,Windows 也不提供每进程权限。权限附加到用户,而不是进程。
如果您从 new
收到“访问被拒绝”的消息,则表明正在运行另一个程序,该程序选择将相同的名称用于其他内容 - 可能是另一个信号量,也可能是其他内容,例如事件或互斥体 - 并且该进程以不同的用户身份运行。
如果您从 open
收到“访问被拒绝”的消息,那么,除了 new
的可能性之外,也可能是另一个进程已经打开了信号量具有相同名称但尚未授予其他用户完全权限。 Win32::Semaphore->open
请求 SEMAPHORE_ALL_ACCESS
permission .
如果信号量已被以同一用户身份运行的进程打开,那么您不应收到“访问被拒绝”的消息。在这种情况下,new
和 open
都不应该失败,尽管 $^E
无论如何都可能保存 183 (ERROR_ALREADY_EXISTS
)。
关于windows - 设置信号量的访问权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1456405/