9

我的场景:一台服务器和一些客户端(虽然不多)。服务器一次只能响应一个客户端,因此必须排队。我正在使用互斥锁 ( boost::interprocess::interprocess_mutex) 来执行此操作,包裹在boost::interprocess::scoped_lock.

问题是,如果一个客户端在持有互斥锁时意外死亡(即没有析构函数运行),其他客户端就会遇到麻烦,因为它们正在等待该互斥锁。我考虑过使用定时等待,所以如果我的客户端等待 20 秒并且没有获得互斥锁,它会继续与服务器对话。

这种方法的问题:1)它每次都这样做。如果它处于循环中,不断与服务器通信,则每次都需要等待超时。2)如果有三个客户端,其中一个在持有互斥锁时死亡,另外两个将等待 20 秒并同时与服务器通信——这正是我试图避免的。

那么,我怎么能对客户说,“嘿,看来这个互斥体已被放弃,拥有它”?

4

1 回答 1

8

不幸的是, boost::interprocess API 不支持这一点。但是,有几种方法可以实现它:

如果您在支持 pthread_mutexattr_setrobust_np 的 POSIX 平台上,请编辑 boost/interprocess/sync/posix/thread_helpers.hpp 和 boost/interprocess/sync/posix/interprocess_mutex.hpp 以使用强大的互斥锁,并以某种方式处理从 pthread_mutex_lock 返回的 EOWNERDEAD .

如果您在其他平台上,您可以编辑 boost/interprocess/sync/emulation/interprocess_mutex.hpp 以使用生成计数器,锁定标志位于低位。然后您可以创建一个回收协议,该协议将在锁定字中设置一个标志以指示待处理的回收,然后在超时后进行比较和交换以检查同一代是否仍在锁定字中,如果是则替换它具有锁定的下一代价值。

如果您在 Windows 上,另一个不错的选择是使用本机互斥对象;无论如何,他们可能会比忙着等待更有效率。

您可能还想重新考虑使用共享内存协议——为什么不使用网络协议呢?

于 2009-07-24T19:40:59.383 回答