【问题标题】:Check if mutex exists system-wide in python检查python中是否存在系统范围内的互斥锁
【发布时间】:2019-08-05 23:38:24
【问题描述】:

我有一个 python 程序,它可能在任何时候被某个调度程序调用多次。

它按照某种模式生成一个字符串,我想确保这个字符串不是由同时运行的另一个进程生成的(锁定字符串)。如果是这样,它必须按照相同的模式生成一个新字符串,并再次检查 if 不存在。如果一个进程结束,相关的字符串可以被一个新的(解锁字符串)重用。

例子:

t=0 
  process 1 - "string_1"

t=1 (process_1 finished)
  process 2 - "string_1"
  process 3 - "string_2" (cause "string_1" already exists)

t=2 (process 2 and 3 still running)
  process 4 - "string_3"

t=3 (procces 3 finished)
  process 5 - "string_2"

and so on...

任何想法如何基于字符串实现这种“某种”系统范围的互斥锁?

【问题讨论】:

    标签: python python-3.x mutex


    【解决方案1】:

    您可以使用一些全局资源(例如文件系统)来协调进程。 创建一个名为 /tmp/string_1 的文件来声明该字符串,或将 string_1 附加到 /tmp/log 或其他内容。 如果需要,使用文件系统锁定,或协调 mutex

    但是将 uuid 附加到每个字符串会更简单。 高熵唯一 ID 为 easy to generate。 根据请求率,您或许可以避免使用截断的 ID。

    如果您确实需要计数器,请考虑让一个生产者来维护它,并分发唯一的 ID。 最简单的方法是通过queue。 生产者写入队列,消费者从中读取 ID。

    【讨论】:

      【解决方案2】:

      让我们将此代码作为我想要使用 fcntl 的示例:

      import fcntl, time
      
      def my_function():
          n = 0
          while n < 10:
              str = "string_{}".format(n)
              try:
                  f = open('/tmp/{}'.format(str))
                  print("Attempting to lock {}".format(f.name))
                  fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
                  time.sleep(3)
                  return str
              except IOError:
                  n += 1
          if n == 10:
              raise Exception("All options are in use")
      
      def main():
          str = my_function()
          print(str)
          time.sleep(5)
      
      if __name__ == "__main__":
          main()
      

      这里的问题是,当my_function() 完成时,锁定就消失了,如果我当时调用这个脚本(在 main() 结束之前),它会选择相同的字符串。有没有办法在整个脚本结束执行之前保持该锁定?

      【讨论】:

      • 您的主要抱怨似乎是关于脚本/锁的生命周期,您希望将锁持有更长时间。你拿着它 3s 但不是完整的 8s。请注意,锁的持续时间与打开文件描述符的持续时间完全相同。当您退出该函数时,cPython 将f 上的引用计数减少到零,因为它超出了范围,并关闭文件描述符,释放锁。要使该特定锁长期存在,您必须使描述符保持活动状态。例如,该函数可以返回一个(名称,filedesc)元组给main,你可以让main负责关闭/释放它。
      猜你喜欢
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      相关资源
      最近更新 更多