使用互斥的Windows上的线程的IPC连接

IPC connection with thread on Windows using Mutex

本文关键字:线程 IPC 连接 Windows      更新时间:2023-10-16

我有一个关于Windows IPC的问题。我在 Windows 上实现了带有互斥锁的 IPC,但是当我与另一个线程建立连接时出现问题;当线程终止时,连接将关闭。

  1. 连接线程 (A( 与服务器建立连接
  2. 主线程 (B( 使用 A 返回的连接句柄(全局变量(
  3. A 终止
  4. B 无法再引用句柄 - 因为连接已关闭

进程终止时,互斥锁被释放是很自然的。但是,在线程的情况下,如果进程处于活动状态,我需要保持互斥锁以保持连接的方法,即使线程终止也是如此。

信号量可以在Linux上替代,但是,在Windows上,无法使用信号量,因为它无法感知异常断开连接。

有人知道吗?

拥有互斥锁的线程退出时,无法阻止释放互斥锁的所有权。

根据

具体情况,您还可以通过多种其他方法解决问题。

1(您可以更改客户端上的任何代码吗? 例如,如果客户端可执行文件使用您提供的用于建立和维护连接的 DLL,则可以更改 DLL,使其使用更合适的对象(如命名管道(而不是互斥锁,或者可以让 DLL 启动自己的线程以拥有互斥锁。

2( 是否有多个客户端? 据推测,由于您使用的是互斥锁,因此您一次只期望一个客户端连接。 如果可以安全地假设一次只连接一个客户端,那么当服务器检测到互斥锁已被放弃时,它可以关闭自己的互斥锁句柄。 当客户端进程退出时,互斥锁将自动删除,因此服务器可以定期检查它是否仍然存在。

3( 客户端如何与服务器通信? 服务器可能正在为客户端做一些有用的事情,因此必须有另一个通信通道以及互斥锁。 例如,如果客户端正在打开到服务器的命名管道,则可以使用该连接而不是互斥锁来检测客户端进程何时退出。 或者,如果通信通道允许您确定客户端的进程 ID,则可以打开进程的句柄并使用它来检测客户端进程何时退出。

4( 如果没有其他解决方案有效,并且您被迫重写客户端和服务器,请考虑使用更合适的 IPC 形式,例如命名管道。

附加

5( 通常的做法是使用进程句柄来等待(或测试(进程终止。 大多数情况下,这些句柄是在创建进程时为父级生成的句柄,但没有理由不使用 OpenProcess 生成的句柄。 就先例而言,我向您保证,使用OpenProcess生成的句柄来监视客户端进程的先例至少与使用互斥锁的先例一样多;您完全有可能是第一个尝试使用 Windows 互斥锁来检测进程是否已退出的人。:-)

6(大概SQLDisconnect((函数正在调用ReleaseMutex以断开与服务器的连接。 由于它是从不拥有互斥锁的线程执行此操作的,因此除了返回错误代码外,它不会执行任何操作,因此您的服务器没有合理的方法来检测这种情况的发生。 该函数是否也在互斥锁上调用 CloseHandle? 如果是这样,您可以使用 (2( 中的方法检测何时发生这种情况。 这既适用于对 SQLDisconnect(( 的调用,也适用于进程退出时。 有多个客户端并不重要,因为它们使用不同的互斥锁。

6a(我说"没有合理的方法",因为你可以想象使用钩子来改变ReleaseMutex的行为。 这不是一个好的选择。

7(你应该仔细检查SQLDisconnect((函数除了调用ReleaseMutex和/或CloseHandle之外做了什么。 您完全有可能通过互斥锁以外的其他方式检测到断开连接。