【问题标题】:Wait until a mutex is created in Python (win32)等到在 Python (win32) 中创建互斥锁
【发布时间】:2013-03-09 17:33:19
【问题描述】:

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

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

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

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

在创建互斥体之前如何进行阻塞?是否有任何 Python 或库方法允许这样做?

【问题讨论】:

  • 您可以使用 CreateMutex API,它能够“打开”一个现有的互斥锁,或者如果它不存在就真正创建它。但这可能需要 C# 方面的合作,如果您先创建它,它可能在“创建”时没有所有权。另一种解决方案:在 mutext 不存在时循环(在循环中使用 Sleep)
  • 当前 pywin32 win32con 模块没有名为 MUTEX_ALL_ACCESS 的常量
  • 需要使用win32事件机制吗?

标签: python winapi mutex


【解决方案1】:

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

while True:

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

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

【讨论】:

    【解决方案2】:

    请注意,使用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
    

    注意setEventcall。

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

    【讨论】:

    • 这是一个糟糕的答案。如果尚未创建互斥体,则 OpenMutex 调用将失败!
    • 嗯,是的,它回答了您要求的“我如何才能阻止直到”部分,但不能解决您遇到的整个问题。我已将答案缩减为仅提供有关如何无限期阻止的信息。
    • 不,如果您无法打开互斥锁,您不能等待它。您是否注意到“直到”部分之后的“已创建”?你真的应该删除这个答案。
    • .. 或扩展它以说明这一点并提供完整的答案,而不仅仅是提供信息的贡献。完成。
    猜你喜欢
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多