我有一个每五分钟就在cron上运行一个进程.通常,运行只需几秒钟,但有时需要几分钟.我想确保一次只运行一个版本.
我试了一个明显的方法......
File.open("/tmp/indexer_lock.tmp",'w') do |f|
exit unless f.flock(File::LOCK_EX)
end
Run Code Online (Sandbox Code Playgroud)
...但它没有测试它是否可以获得锁定,它会在锁定被释放之前阻塞.
知道我错过了什么吗?我宁愿不使用ps来破解某些东西,但这是另一种选择.
sma*_*thy 23
我知道这是旧的,但对于任何有兴趣的人,都有一个非阻塞常量可以传递给flock,以便它返回而不是阻塞.
File.new("/tmp/foo.lock").flock( File::LOCK_NB | File::LOCK_EX )
Run Code Online (Sandbox Code Playgroud)
flock如果此进程收到锁定,则返回true ,否则返回false.因此,要确保一次只运行一个进程,您只想尝试获取锁定,如果无法执行则退出.它就像放在exit unless我上面的代码行前面一样简单:
exit unless File.new("/tmp/foo.lock").flock( File::LOCK_NB | File::LOCK_EX )
Run Code Online (Sandbox Code Playgroud)
根据您的需要,这应该可以正常工作,并且不需要在任何地方创建另一个文件。
exit unless DATA.flock(File::LOCK_NB | File::LOCK_EX)
# your script here
__END__
DO NOT REMOVE: required for the DATA object above.
Run Code Online (Sandbox Code Playgroud)
小智 3
虽然这并没有直接回答您的问题,但如果我是您,我可能会编写一个守护程序脚本(您可以使用http://daemons.rubyforge.org/)
您可以通过名为 script/index 的包装器脚本运行索引器(假设其 indexer.rb),例如:
require 'rubygems'
require 'daemons'
Daemons.run('indexer.rb')
Run Code Online (Sandbox Code Playgroud)
你的索引器几乎可以做同样的事情,除了你指定一个睡眠间隔
loop do
# code executing your indexing
sleep INDEXING_INTERVAL
end
Run Code Online (Sandbox Code Playgroud)
这就是作业处理器与队列服务器通常协同工作的方式。