【问题标题】:Python2.6.5 : Is there python equivalent of Java Semaphore tryAcquirePython2.6.5:是否有 Python 等效于 Java Semaphore tryAcquire
【发布时间】:2013-06-17 08:41:53
【问题描述】:

我正在为 Java 的 tryAcquire Semaphore 函数寻找 python 替代方案。我发现这个函数是在 python 版本 3 及更高版本中添加的。我正在使用 python 版本 2.6.5。我有什么选择吗?我这里只有 semaphore.acquire(blocking=False) 这是我的 Java 代码 - (信号量发布在另一个我没有包含代码的线程中完成)

if(Sem.tryAcquire(30, TimeUnit.SECONDS))   
   log.info("testCall Semaphore acquired ");
else 
   log.error("Semaphore Timeout occured");

【问题讨论】:

  • threading.Lock 可以工作吗?看看here
  • No threading.Lock 也类似于 threading.semaphore。不提供超时!我在想可能是我可以使用 sem.acquire 和使用 threading.timer 循环。但是计时器在其他线程中唤醒。调用 timer.start 后,我​​的主线程将继续执行,这就是 timer 的问题!

标签: python multithreading semaphore blocking


【解决方案1】:

Semaphore 是用纯 Python 实现的 - 参见 http://hg.python.org/cpython/file/3.3/Lib/threading.py ,从第 236 行开始。acquire 方法是这样实现的:

def acquire(self, blocking=True, timeout=None):
    if not blocking and timeout is not None:
        raise ValueError("can't specify timeout for non-blocking acquire")
    rc = False
    endtime = None
    with self._cond:
        while self._value == 0:
            if not blocking:
                break
            if timeout is not None:
                if endtime is None:
                    endtime = _time() + timeout
                else:
                    timeout = endtime - _time()
                    if timeout <= 0:
                        break
            self._cond.wait(timeout)
        else:
            self._value = self._value - 1
            rc = True
    return rc

self._cond 是一个 Condition 包装一个 Lock

您可以直接在代码中使用Semaphore 的技术而不是使用类,但是将整个类复制到您自己的代码中可能会更容易。如果前向兼容性是一个问题,您甚至可以像这样调整它:

from threading import *
from sys import version_info

if version_info < (3, 2):
    # Need timeout in Semaphore.acquire,
    # from Python 3.3 threading.py
    class Semaphore:
        ...

无论您采用哪种方式,您还需要新的 Condition 类 - 根据 Condition.wait 的文档,

返回值为True,除非给定的超时已过期,在这种情况下 是False

在 3.2 版中更改:以前,该方法总是返回 None

Semaphore 超时代码依赖于这种行为。兔子洞似乎并没有比这更深,但是,您最简单的解决方案甚至可能是复制整个 3.3 threading.py,进行在 2.x 上运行所需的任何更改,并在顶部添加一个显眼的注释,说明您故意隐藏标准库。

【讨论】:

  • 所以,我已将 Condition 和 Semaphore 放入我自己的文件中,里面的 version_info 检查。但是,在初始化信号量并调用“获取”时,我的代码似乎仍会转到内置类。它给了我 - acquire() 得到了一个意想不到的关键字参数 'timeout' 。我正在从另一个文件中调用获取,在该文件中我声明了 from forms.py import Semaphore ...。知道我应该提供什么更多的声明吗?
  • @Ivc 好的,流程现在进入我的代码。我定义了上面的代码!谢谢
  • 不,解决方案不起作用。信号量需要 Condition 需要 Lock。所以我把这三个都复制了。但是 Lock 实现仍然需要 thread.allocate_lock 所以我尝试了第二种方法 - 复制整个 threading.py 。然而,在 2.6 上运行这个文件似乎是一项艰巨的任务。代码很多,依赖3.x python版本。错误不会消失!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 2010-12-19
  • 2020-10-22
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
相关资源
最近更新 更多