如何使用'with'从上下文管理器获取"result"



我发现了一个文件锁定类的演示(此处:https://groups.google.com/forum/#!topic/pug pe/mQr7KX cenU),但我不太了解使用它的机制。

@contextmanager
def FileLock(lock_file):
    if os.path.exists(lock_file):
        print 'Only one script can run at once. '
              'Script is locked with %s' % lock_file
        sys.exit(-1)
    else:
        open(lock_file, 'w').write("1")
        try:
            yield
        finally:
            os.remove(lock_file)

我相信上面写着"如果传入的文件不存在,打开它。完成后,删除它。

演示的用途是:

with FileLock('/tmp/my_script.lock'):
    print "I am here and I am sleeping for 10 sec..."
    time.sleep(10)

它工作正常-如果我运行脚本一次,我看到"我在这里,我睡了10秒…",如果我在这10秒内再次运行,我会看到"一次只能运行一个脚本。脚本用/tmp/my_script.lock锁定"。然而,要使用文件锁,通常需要"等到获得锁"才能执行操作。然而,'sys.exit()'似乎阻止了这种情况的发生。似乎我想用某种方式将"with"包装在while循环中?类似于:

while fileIsLocked:
    with FileLock('/tmp/my_script.lock'): # try to get the lock
        print "I am here and I am sleeping for 10 sec..."
        time.sleep(10)

但我不知道如何从FileLock中获取返回值。有人能解释一下怎么做吗?

您应该使用以下内容:

@上下文管理器def FileLock(lock_file):当os.path.存在时(lock_file):print'一次只能运行一个脚本。'\'脚本被%s锁定了'%lock_file时间睡眠(1)打开(lock_file,'w').write("1")尝试:产量最后:os.remove(锁定文件)

这直接满足了声明的需求。OTOH该方法非常有缺陷,因为在检查文件存在和打开文件之间存在明确的竞争条件。更稳定的方法应该使用O_EXCL来确保文件在创建过程中不存在,或者使用flock来锁定文件内容,而不是其存在。此外,还可以使用一些内核级IPC(Posix信号量、SysV信号量等)

我接受了Netch的回答,因为它既展示了我"声明"的需求的解决方案,又推荐了一个更好的解决方案。为了完整起见,我在这里发布了羊群的使用。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import fcntl
import time
try:
  f = open('/tmp/locktest', 'w')
  fcntl.flock(f, fcntl.LOCK_EX) # Get an exclusive lock - this will block until it gets the lock
  print "Sleeping..."
  time.sleep(10)
except IOError:
  print("can't immediately write-lock the file ($!), blocking ...")
else:
  print("No error")
  print("End of file")

相关内容

  • 没有找到相关文章

最新更新