在Python(win32)中等待互斥锁创建
我正在使用win32event这个Python模块来和另一个程序(基于C#)创建的互斥量(Mutex)进行交互。
我的代码是打开一个互斥量,然后在上面等待:
hWait = win32event.OpenMutex(win32con.MUTEX_ALL_ACCESS, False, "mutexname")
win32event.WaitForSingleObject(hWait, 20000)
这段代码的问题在于,如果互斥量还没有被创建(比如说,如果Python程序在C#程序创建它之前就尝试打开它),那么代码就会失败。
我该如何阻止程序继续运行,直到互斥量被创建?有没有什么Python的方法或者库可以做到这一点?
2 个回答
0
注意,当使用 win32event.WaitForSingleObject
时,不一定要指定一个任意但足够长的等待时间(比如20000毫秒),你也可以直接使用 win32event.INFINITE
,这样就会一直等待,直到某个事件发生,示例如下:
win32event.WaitForSingleObject(waitable, win32event.INFINITE)
这在某些情况下很有用,比如你需要告诉另一个线程,互斥量(mutex)已经打开了。
因为如果互斥量还没有创建,等待它是会失败的,所以我们创建一个事件,当互斥量打开时触发这个事件。
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
线程会收到通知,知道互斥量现在已经打开了。
0
正如@manuell在评论中提到的,简单的解决办法是不断循环,直到互斥锁被创建,同时默默地捕捉当互斥锁还不存在时出现的错误:
while True:
try:
hWait = win32event.OpenMutex(MUTEX_ALL_ACCESS, False, "mutexname")
except pywintypes.error:
pass
else:
break
根据你的具体情况,你可能想在循环中明确地让程序暂停一会儿,或者把这个等待的循环放到一个单独的线程中,或者把它变成一个生成器或协程,甚至可以用它来触发一个win32事件,以便在另一个已经运行的线程中执行某些操作(你可以看看我其他的回答,了解如何等待一个事件直到它发生)。