Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 使用命名互斥体的存在作为指示器是一个好主意吗?_Winapi_Mutex - Fatal编程技术网

Winapi 使用命名互斥体的存在作为指示器是一个好主意吗?

Winapi 使用命名互斥体的存在作为指示器是一个好主意吗?,winapi,mutex,Winapi,Mutex,我使用命名互斥来检测应用程序的其他实例并相应退出,发现有两种方法可以做到这一点: 创建互斥体;忽略是否已经存在的指示;试着获得它;使用获取成功/失败的事实 创建互斥体;使用指示是否已经存在 我无法决定是否获取互斥(并在退出时释放)。一方面,获取+释放虽然没有明显区别,但看起来像是货物崇拜,但另一方面,互斥对象的存在听起来像是其实际预期功能的副作用 那么,我应该执行#1还是#2来检测应用程序是否已经在运行?我不确定,但是如果程序崩溃并且没有正确终止,指定的互斥锁可能仍然存在。如果是这样,存在性测试

我使用命名互斥来检测应用程序的其他实例并相应退出,发现有两种方法可以做到这一点:

  • 创建互斥体;忽略是否已经存在的指示;试着获得它;使用获取成功/失败的事实
  • 创建互斥体;使用指示是否已经存在
  • 我无法决定是否获取互斥(并在退出时释放)。一方面,获取+释放虽然没有明显区别,但看起来像是货物崇拜,但另一方面,互斥对象的存在听起来像是其实际预期功能的副作用


    那么,我应该执行#1还是#2来检测应用程序是否已经在运行?

    我不确定,但是如果程序崩溃并且没有正确终止,指定的互斥锁可能仍然存在。如果是这样,存在性测试将成功,而没有其他实例正在运行。因此,我个人更愿意尝试获得它;-)

    #1听起来是你应该走的路

    创建互斥体;忽略是否已经存在的指示;试着获得它;使用获取成功/失败的事实


    因为您的应用程序启动代码可能会执行两次(在简历或类似的操作系统中),即使互斥体已经存在,因为它是由相同的应用程序id创建的。表示互斥体已经存在的指示足以让您知道至少还有一个其他进程,获取也会成功。没有必要为此使用互斥锁

    但是,只要您拥有互斥锁,如果需要将其他实例锁定在某段代码之外,就可以使用它

    例如,在退出初始化代码之前,可以一直使用互斥锁。这样,一次只能有一个程序实例处于初始化状态。如果您在打开互斥体之后获取它,那么首先获取互斥体的人知道其init代码中没有其他实例。但更重要的是,没有创建互斥体的人知道创建互斥体的人已经完成了初始化


    这样,如果实例2想要与实例1对话,它知道一旦实例1能够进入互斥体至少一次,它就准备好了侦听。如果您按照最初发出的信号创建互斥体,以绝对确保创建者成为第一个所有者,则效果会更好。

    但是创建是一个原子操作-您始终可以获得句柄(假设安全检查成功),并且可以检查互斥体是否已经存在,并带有GetLastError。另外,我的应用程序启动代码怎么能执行两次呢?我很确定这需要重新启动程序。一般来说,我在移动设备上见过这种情况。当操作系统将应用程序置于备用状态或执行GC时。如果您再次获得应用程序的焦点,它将重新启动,并传递一个捆绑包以恢复以前的状态。哦,我明白了。是的,WinMobile喜欢随意关闭/重新启动应用程序,但我正在为成熟的操作系统撰写文章。MSDN提到终止的进程所持有的句柄被释放,并且互斥锁在没有句柄保留时被删除,因此我非常确定情况并非如此。感谢您的确认。请注意,我在这里的回答中写了一个如何在C#(不是原始的WinAPI!)中实现这一点的示例: