2

我正在使用win32event Python 模块与在另一个程序中创建的 Mutex 交互(基于 C#)

我的代码打开一个互斥体,然后等待它:

hWait = win32event.OpenMutex(win32con.MUTEX_ALL_ACCESS, False, "mutexname")
win32event.WaitForSingleObject(hWait, 20000)

这段代码的问题在于,如果尚未创建互斥锁,它会失败(例如,如果 python 程序在 C# 程序创建互斥锁之前尝试打开它)。

在创建互斥锁之前如何阻止?是否有任何允许这样做的 Python 或库方法?

4

2 回答 2

0

正如@manuell(在评论中)所指出的那样,简单的解决方案是循环直到创建互斥锁,静默捕获互斥锁尚不存在时引发的错误:

while True:

   try:
      hWait = win32event.OpenMutex(MUTEX_ALL_ACCESS, False, "mutexname")
   except pywintypes.error:
      pass
   else:
      break

根据您的具体情况,您可能希望在循环内显式地休眠一点,将等待循环放在单独的线程中,或将其转换为生成器或协程,或使用它来触发运行 win32 事件另一个已经运行的线程中的某些东西(有关如何等待事件直到它发生,请参阅我的其他答案)。

于 2016-10-27T09:26:06.843 回答
0

请注意,当使用 时win32event.WaitForSingleObject,而不是指定一些任意但足够长的时间来等待(20000),也可以简单地使用win32event.INFINITE无限期地阻塞直到事件发生,如:

win32event.WaitForSingleObject(waitable, win32event.INFINITE)

例如,当您需要告诉另一个线程中的代码互斥锁已打开时,这可能很有用。

由于如果尚未创建互斥锁,则等待互斥锁会失败,因此我们改为创建一个事件以在互斥锁打开时触发。

mutex_open = win32event.CreateEvent(None, 0, 0, None)

然后启动一个等待事件的线程:

def wait_for_opening(open_evt):
   win32event.WaitForSingleObject(open_evt, win32event.INFINITE)
   print("Got notified that mutex is now open.")

waiter = threading.Thread(target=wait_for_opening, args=(mutex_open,))
waiter.start()

要模拟另一个程序,请在一段时间后启动另一个创建互斥锁的线程:

def delayed_create():
   time.sleep(1)
   m = CreateMutex(None, True, u"mutexname")

creator = threading.Thread(target=delayed_create)
creator.start()

最后,运行等待互斥锁打开的循环,然后设置事件。

while True:

   try:
      hWait = win32event.OpenMutex(MUTEX_ALL_ACCESS, False, "mutexname")
   except pywintypes.error:
      pass
   else:
      win32event.SetEvent(mutex_open)
      break

注意setEvent通话。

因此,在运行代码时,一段时间后,waiter线程会收到通知说互斥锁现在已打开。

于 2016-10-27T08:09:15.577 回答