5

我正在使用 python-zookeeper 进行锁定,并且我试图找出一种让执行在它正在观看文件时等待通知的方法,因为它会zookeeper.exists()立即返回,而不是阻塞。

基本上,我有下面列出的代码,但我不确定实现notify()andwait_for_notification()功能的最佳方式。可以用os.kill()and来完成signal.pause(),但我敢肯定,如果我以后在一个程序中有多个锁,这可能会导致问题 - 是否有特定的 Python 库对这类事情有好处?

def get_lock(zh):
    lockfile = zookeeper.create(zh,lockdir + '/guid-lock-','lock', [ZOO_OPEN_ACL_UNSAFE], zookeeper.EPHEMERAL | zookeeper.SEQUENCE)

    while(True):
        # this won't work for more than one waiting process, fix later
        children = zookeeper.get_children(zh, lockdir)
        if len(children) == 1 and children[0] == basename(lockfile):
            return lockfile

        # yeah, there's a problem here, I'll fix it later
        for child in children:
            if child < basename(lockfile):
                break

        # exists will call notify when the watched file changes
        if zookeeper.exists(zh, lockdir + '/' + child, notify):
            # Process should wait here until notify() wakes it
            wait_for_notification()


def drop_lock(zh,lockfile):
    zookeeper.delete(zh,lockfile)

def notify(zh, unknown1, unknown2, lockfile):
    pass

def wait_for_notification():
    pass
4

2 回答 2

9

Python 的 threading 模块中的 Condition 变量可能非常适合您尝试执行的操作:

http://docs.python.org/library/threading.html#condition-objects

我已经扩展到该示例,以使其更明显地适应您的目的:

#!/usr/bin/env python

from collections import deque
from threading import Thread,Condition

QUEUE = deque()

def an_item_is_available():
    return bool(QUEUE)

def get_an_available_item():
    return QUEUE.popleft()

def make_an_item_available(item):
    QUEUE.append(item)

def consume(cv):
    cv.acquire()
    while not an_item_is_available():
        cv.wait()
    print 'We got an available item', get_an_available_item()
    cv.release()

def produce(cv):
    cv.acquire()
    make_an_item_available('an item to be processed')
    cv.notify()
    cv.release()

def main():
    cv = Condition()
    Thread(target=consume, args=(cv,)).start()    
    Thread(target=produce, args=(cv,)).start()

if __name__ == '__main__':
    main()
于 2012-10-02T08:33:59.393 回答
0

我的回答可能与您的问题无关,但与问题标题有关。

from threading import Thread,Event

locker = Event()

def MyJob(locker):
    while True:
        #
        # do some logic here
        #
        locker.clear() # Set event state to 'False'
        locker.wait() # suspend the thread until event state is 'True'

worker_thread = Thread(target=MyJob, args=(locker,))
worker_thread.start()

#
# some main thread logic here
#
locker.set() # This sets the event state to 'True' and thus it resumes the worker_thread

更多信息在这里:https ://docs.python.org/3/library/threading.html#event-objects

于 2021-05-27T21:29:27.150 回答