我对Windows IPC有疑问。我在Windows上使用mutex实现了IPC,但是当我与另一个线程建立连接时出现问题;当线程终止时,连接关闭。
当进程终止时,释放互斥锁是很自然的。但是,在线程的情况下,如果进程处于活动状态,即使线程终止,我也需要保持互斥锁以保持连接的方式。
信号量可以作为Linux上的替代品,但是,在Windows上,不可能使用信号量,因为它无法感知异常断开连接。
有人有任何想法吗?
答案 0 :(得分:1)
当拥有它的线程退出时,无法阻止互斥锁的所有权被释放。
根据具体情况,您可以通过许多其他方式解决问题。
1)您可以更改客户端上的任何代码吗?例如,如果客户端可执行文件使用您提供的DLL来建立和维护连接,则可以更改DLL以使其使用更合适的对象(例如命名管道)而不是互斥锁,或者您可以获取DLL以启动自己的线程来拥有互斥锁。
2)是否有多个客户?据推测,由于您使用的是互斥锁,因此您只希望一次连接一个客户端。如果您可以安全地假设一次只连接一个客户端,那么当服务器检测到互斥锁已被放弃时,它可以关闭它自己的互斥锁句柄。当客户端进程退出时,将自动删除互斥锁,因此服务器可以定期检查它是否仍然存在。
3)客户端如何与服务器通信?服务器可能对客户端做了一些有用的事情,因此必须有另一个通信通道以及互斥锁。例如,如果客户端打开到服务器的命名管道,则可以使用该连接而不是互斥锁来检测客户端进程何时退出。或者,如果通信通道允许您确定客户端的进程ID,则可以打开进程的句柄并使用它来检测客户端进程何时退出。
4)如果没有其他解决方案可行,并且您被迫重写客户端以及服务器,请考虑使用更合适的IPC形式,例如命名管道。
其他
5)通常的做法是使用进程句柄等待(或测试)进程终止。通常,这些句柄是在创建进程时为父进程生成的句柄,但没有理由不使用OpenProcess生成的句柄。就先例而言,我向您保证,至少使用OpenProcess生成的句柄监视客户端进程的先例与使用互斥锁一样多;您是第一个尝试使用Windows互斥锁来检测进程已退出的人。 : - )
6)可能SQLDisconnect()函数正在调用ReleaseMutex以断开与服务器的连接。由于它是从不拥有互斥锁的线程执行此操作,除了返回错误代码之外不会执行任何操作,因此您的服务器没有合理的方法来检测发生的情况。该函数是否还在互斥锁上调用CloseHandle?如果是这样,您可以使用(2)中的方法来检测何时发生这种情况。这对于调用SQLDisconnect()和进程退出都有效。有多个客户端并不重要,因为它们使用不同的互斥锁。
6a)我说“没有合理的方式”,因为你可以想象使用hooking来改变ReleaseMutex的行为。 这不是一个好的选择。
7)除了调用ReleaseMutex和/或CloseHandle之外,您应该仔细检查SQLDisconnect()函数的作用。您完全有可能通过除互斥锁之外的其他方式检测断开连接。