我有两个程序,X是用户交互的正常程序,程序Y清理程序Y获取的资源。可以有多个X实例但只有一个Y(我已经解决了那个部分)用命名的互斥体)。现在,由于Y是一个清理程序,它应该被阻塞,直到X的最后一个实例消失。
我尝试使用信号量,但我无法理解。有人可以帮帮我吗?
答案 0 :(得分:1)
信号量是一种这样做的有效方式,但不一定是最好的。每当程序X启动时,请致电ReleaseSemaphore
。每当进程终止时,在信号量句柄上调用WaitForSingleObject
超时为零(确保在异常处理程序中也包含此项,以防程序崩溃)。
进程Y可以定期轮询WaitForSingleObject
,然后超时(或几毫秒)。如果返回值为WAIT_OBJECT_0
,则必须立即再次释放信号量(否则它将阻止尝试退出的最后一个X进程!)。如果返回值为WAIT_TIMEOUT
,则不再有X进程。
最佳解决方案当然是从Y启动所有X进程。在这种情况下,Y只能WaitForMultipleObjects
来自CreateProcess
的进程句柄没有额外的“ifs and whens”。这将永远“正常工作”。它也更有效率
这导致了第二个最佳解决方案......通过OpenProcess
和WaitForMultipleObjects
获取正在运行的流程的句柄。问题是从哪里获取进程ID。可能有共享内存区域,管道可能会这样做,或者CreateToolhelp32Snapshot
可能会提供该信息。
另一种方法是使用命名的互斥对象。所有进程X都调用CreateMutex
。如果互斥锁已经存在,则不会造成任何伤害(GetLastError将返回ERROR_ALREADY_EXISTS
,但是那样)。如果进程终止或崩溃,则关闭所有打开的句柄,从而减少互斥引用计数
Y进程调用OpenMutex
。这要么成功要么失败。如果成功,它会再次关闭手柄,休眠并再次尝试。如果失败,则没有单个X进程正在运行。
另一种方式(虽然它可能有种族问题)将创建一个命名的共享内存段,并在进程X的启动和退出时调用InterlockedIncrement
和InterlockedDecrement
。如果无法打开共享内存对象或计数器为零,则进程Y知道没有X进程正在运行。