假设你的Python解释器,以及底层的os和文件系统把os.rename当作一个primefaces操作,当目的地存在时它将会出错,下面的方法没有竞争条件。 我正在linux机器上使用它。 不需要第三方库,也不依赖于操作系统,除了创build额外的文件之外,对于许多用例来说性能指标是可以接受的。 你可以很容易地应用Python的函数装饰器模式或一个'with_statement'上下文pipe理器来抽象出混乱。
您需要确保在新进程/任务开始之前lock_filename不存在。
import os,time def get_tmp_file(): filename='tmp_%s_%s'%(os.getpid(),time.time()) open(filename).close() return filename def do_exclusive_work(): print 'exclusive work being done...' num_tries=10 wait_time=10 lock_filename='filename.lock' acquired=False for try_num in xrange(num_tries): tmp_filename=get_tmp_file() if not os.path.exists(lock_filename): try: os.rename(tmp_filename,lock_filename) acquired=True except (OSError,ValueError,IOError), e: pass if acquired: try: do_exclusive_work() finally: os.remove(lock_filename) break os.remove(tmp_filename) time.sleep(wait_time) assert acquired, 'maximum tries reached, failed to acquire lock file'
编辑
已经发现os.rename默默地覆盖了非windows操作系统上的目的地。 感谢您指出@ akrueger!
这里是一个解决方法,从这里收集:
而不是使用os.rename,你可以使用:
try: if os.name != 'nt': # non-windows needs a create-exclusive operation fd = os.open(lock_filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL) os.close(fd) # non-windows os.rename will overwrite lock_filename silently. # We leave this call in here just so the tmp file is deleted but it could be refactored so the tmp file is never even generated for a non-windows OS os.rename(tmp_filename,lock_filename) acquired=True except (OSError,ValueError,IOError), e: if os.name != 'nt' and not 'File exists' in str(e): raise
@ akrueger对于基于目录的解决scheme,您可能没有问题,只是给你一个替代方法。