等待最后一个程序实例

时间:2011-07-13 16:20:54

标签: windows winapi multiprocessing

我有两个程序,X是用户交互的正常程序,程序Y清理程序Y获取的资源。可以有多个X实例但只有一个Y(我已经解决了那个部分)用命名的互斥体)。现在,由于Y是一个清理程序,它应该被阻塞,直到X的最后一个实例消失。

我尝试使用信号量,但我无法理解。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:1)

信号量是一种这样做的有效方式,但不一定是最好的。每当程序X启动时,请致电ReleaseSemaphore。每当进程终止时,在信号量句柄上调用WaitForSingleObject超时为零(确保在异常处理程序中也包含此项,以防程序崩溃)。
进程Y可以定期轮询WaitForSingleObject,然后超时(或几毫秒)。如果返回值为WAIT_OBJECT_0,则必须立即再次释放信号量(否则它将阻止尝试退出的最后一个X进程!)。如果返回值为WAIT_TIMEOUT,则不再有X进程。

最佳解决方案当然是从Y启动所有X进程。在这种情况下,Y只能WaitForMultipleObjects来自CreateProcess的进程句柄没有额外的“ifs and whens”。这将永远“正常工作”。它也更有效率 这导致了第二个最佳解决方案......通过OpenProcessWaitForMultipleObjects获取正在运行的流程的句柄。问题是从哪里获取进程ID。可能有共享内存区域,管道可能会这样做,或者CreateToolhelp32Snapshot可能会提供该信息。

另一种方法是使用命名的互斥对象。所有进程X都调用CreateMutex。如果互斥锁已经存在,则不会造成任何伤害(GetLastError将返回ERROR_ALREADY_EXISTS,但是那样)。如果进程终止或崩溃,则关闭所有打开的句柄,从而减少互斥引用计数 Y进程调用OpenMutex。这要么成功要么失败。如果成功,它会再次关闭手柄,休眠并再次尝试。如果失败,则没有单个X进程正在运行。

另一种方式(虽然它可能有种族问题)将创建一个命名的共享内存段,并在进程X的启动和退出时调用InterlockedIncrementInterlockedDecrement。如果无法打开共享内存对象或计数器为零,则进程Y知道没有X进程正在运行。