1

我正在为 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");
4

1 回答 1

1

Semaphore is implemented in pure Python - see http://hg.python.org/cpython/file/3.3/Lib/threading.py , starting at line 236. The acquire method is implemented this way:

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 is a Condition wrapping a Lock.

You could use Semaphore's technique directly in your code instead of using the class, but it would probably be easier to copy the entire class into your own code. If forward compatibility is an issue, you could even condition it out like so:

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:
        ...

Whichever way you do this, you will also need the new Condition class - according to the docs for Condition.wait,

The return value is True unless a given timeout expired, in which case it is False.

Changed in version 3.2: Previously, the method always returned None.

The Semaphore timeout code relies on this behavior. The rabbit hole doesn't appear to go any deeper than that, but, your easiest solution might even be to copy the entire 3.3 threading.py, make any changes it needs to run on 2.x, and add a prominent comment at the top that you're deliberately shadowing the stdlib.

于 2013-06-17T09:07:25.550 回答