ida*_*hmu 6 python atomicity python-2.7
我正在写Python 2.7剧本.
总之,这个脚本每晚都在运行Linux并激活多个进程.
我想确保这个脚本不是并行运行多次(基本上是试图模仿Singleton模式但是在应用程序级别).
代码示例
def main():
# before doing anything, I'd like to know whether this
# script was activated and alive.
# if so, error out
# do something
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
建议
天真的解决方案是创建某种锁文件,它充当互斥锁.
我们要做的第一件事就是检查这个文件是否存在.如果是这样,那么脚本的其他实例已经创建了它,我们应该出错.脚本完成后,我们删除此文件.
我假设这个解决方案可行,只要文件系统上的操作是原子的.
履行
import os, sys
lock_file_path = ".lock_script"
def lock_mutex():
if os.path.exists(lock_mutex_path):
print "Error: script was already activated."
sys.exit(-1)
else:
file = open(lock_mutex_path, 'w')
def unlock_mutex():
assert( os.path.exists(lock_mutex_path))
os.remove(lock_mutex_path)
def main():
try:
lock_mutex()
# do something
unlock_mutex()
except:
unlock_mutex()
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
问题
如何确保lock_mutex()并且unlock_mutex()是原子的?
由于您使用的是 linux,您可以使用flock:
import os
import fcntl
import time
def main():
# acquire the prog lock
if not prog_lock_acq('singleton.lock'):
print("another instance is running")
exit(1)
print("program is running-press Ctrl+C to stop")
while True:
time.sleep(10)
def prog_lock_acq(lpath):
fd = None
try:
fd = os.open(lpath, os.O_CREAT)
fcntl.flock(fd, fcntl.LOCK_NB | fcntl.LOCK_EX)
return True
except (OSError, IOError):
if fd: os.close(fd)
return False
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
退出后我们让文件保持打开状态并不重要,prog_lock_acq因为当进程退出时,它会被操作系统自动关闭。此外,如果您省略LOCK_NB选项,flock调用将阻塞,直到当前正在运行的进程退出。根据您的用例,这可能很有用。
请注意,我们不会在退出时删除文件。没关系。文件的存在并不表示一个实时进程——锁可以。所以即使你用 杀死你的进程kill -9,锁仍然被释放。
然而有一个警告:如果你在进程运行时取消锁定文件的链接,当进程的下一个实例运行时,它将创建一个新文件,该文件没有锁定并且运行得很好,这将违反我们的单例设计。您也许可以对目录做一些聪明的事情来防止取消链接,但我不确定这会有多健壮。
我使用 Supervisor ( http://supervisord.org/ ) 在 Linux 下运行东西。它运行 Django、Celeryd 等,并确保它们在意外完成时重新启动。
但也可以设置选项,以便命令在完成时不会自动启动或重新启动:autostart=false、autorestart=false、starseconds=0。我将其用于这些 cron 作业。
在 cron 中,我输入了命令“supervisorctl start myscript”,如果 myscript 已经在主管下运行,则该命令不执行任何操作,否则启动它。
无论脚本是用什么语言编写的,都可以完美运行。
| 归档时间: |
|
| 查看次数: |
1657 次 |
| 最近记录: |