【问题标题】:control access to a resource with two application instances使用两个应用程序实例控制对资源的访问
【发布时间】:2014-08-06 05:37:46
【问题描述】:

我有一个用例,我必须计算我的应用程序的使用情况,哪个功能使用最多。我将所有统计信息存储在一个文件中。每次应用程序关闭时,它都会将统计信息写入该文件。

应用程序是独立的,在服务器中,多个人可以通过运行应用程序同时使用应用程序(所以它就像应用程序的多个副本将在不同的地方运行)。

所以问题是如果多人同时尝试更新统计信息,就有可能得到错误的统计信息(并发控制问题)。那么在python中如何处理这种情况呢?

我将以下数据存储在我的统计文件中::

stats  = {user1 : {feature1 : count, feature2 : count, etc..},
          user2 : {feature1 : count, feature2 : count, etc..}
}

【问题讨论】:

    标签: python concurrency semaphore


    【解决方案1】:

    您可以使用portalocker,这是一个很棒的模块,它为您提供了一种使用文件系统锁的可移植方式。

    如果您仅限于一个平台,则可以使用特定于平台的文件锁定原语,通常通过 python 标准库公开。

    您也可以使用适当的数据库,但这对于手头的任务来说似乎是一个巨大的矫枉过正。

    编辑:看到您即将使用线程锁,不要!线程锁(互斥锁或信号量)仅阻止同一进程中的多个线程访问共享变量,它们跨不同的进程工作,尤其是独立的程序实例!您需要的是文件锁定机制,而不是线程锁。

    【讨论】:

    • 嘿,有没有办法使用内置的 python 模块锁定文件?因为我想尽量减少在我的应用程序中使用的额外第三方包。
    • 有——你的目标平台和python版本是什么?
    • 我正在使用 python 2.7 和 ubuntu-11.04 机器。
    • 然后使用fcntl.lockf。当心——在某些极端情况下它不起作用,例如通过 NFS 或者如果其他一些应用程序尝试在没有锁定的情况下使用文件,它会成功(这是建议锁定,不是强制性的);这些对你来说可能并不重要,所以 lockf 应该可以很好地完成这项工作。
    • fcntl 将适用于大多数基于 srv 的 unix 系统,即所有现代 unix 系统,但是是的,它通常是不可移植的。如果你需要便携性,portalocker 是我迄今为止见过的最好的。通常,文件锁定是一个非常棘手的问题,没有好的解决方案。这就是为什么在某些特定情况下除了使用适当的数据库之外别无选择,或者将 rdbms 重新实现为应用程序的一个单独进程来管理对文件的访问,但是对于像“写入统计信息”这样简单的事情是完全不必要。如果您不需要 Windows,我会说坚持使用 portalocker 或 fnctl。
    【解决方案2】:

    您的问题似乎是读者-作者问题的一种,它扩展到数据库中的事务。我将创建一个 SQL 事务类,它主要负责对您的数据库进行 CRUD 操作。然后我会有一个标志,它可以以与互斥锁非常相似的方式锁定和释放,这样你就可以确保没有两个并发进程在它们的关键部分(在数据库中执行更新或插入)同一时间。

    我还相信有一个读写器锁,专门用于控制对共享资源的访问,您可能会对此感兴趣。

    如果您有任何问题,请告诉我!

    【讨论】:

      【解决方案3】:

      在您的代码中,共享资源可以被多个应用程序使用,使用锁

      import threading
      mylock = threading.Lock()
      
      with mylock:
           ....
           #access the shared resource
      

      【讨论】:

      • 感谢您的回答,我会试一试!如果我尝试使用来自不同不同应用程序的相同资源,它会起作用吗!?
      • 还有没有办法指定超时值?
      • 我对线程概念不是很熟悉。所以我有一个非常基本的问题,如果资源被锁定并且如果其他进程想要写入该资源,那么其他进程会等待资源被释放还是退出?
      • 不,这些锁在进程级别上不起作用。阅读更多关于docs.python.org/2/library/threading.html
      • 我已经编辑了我的问题。请看一下并提出答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多