2007-12-29
A simple inter-process lock
关键字: ruby
Linux程序员通常喜欢用文件锁来做进程间的同步,或简单地用文件锁指示程序进程是否还健在。在ruby里面可以很简单的实现文件锁:
测试代码:
父子进程通过文件锁来同步,子进程持有锁后休眠2秒导致父进程企图获取锁时休眠。最后子进程不在持有锁的时候,父进程不再block。
Win32用户可以在Cygwin下运行此代码。
=begin
file lock for inter-process sync.
usage:
FSLock('mylock') do
# protected by lock,
# do your job here ...
end
=end
class FSLock
def initialize(name=nil)
name ||= 'global'
@fname = name + '.lock'
if block_given?
lock()
yield
unlock()
end
end
def critical
lock()
yield() if block_given?
unlock()
end
def lock
@f = File.new(@fname, "ab")
@f.flock(File::LOCK_EX) if @f
end
def unlock
@f.close if @f
end
end
测试代码:
if $0 == __FILE__
unless fork
# child process
3.times do |i|
FSLock.new('/tmp/myapp') do
sleep 2 # child process sleep while holding the lock
puts "#{Time.now.to_s}: Ping !"
end
end
else
# parent process
sleep 0.1
6.times do
FSLock.new('/tmp/myapp') do # parent process will be blocked while child holding the lock
puts "#{Time.now.to_s}: Pong !"
end
sleep 0.1
end
Process.wait
end
end
父子进程通过文件锁来同步,子进程持有锁后休眠2秒导致父进程企图获取锁时休眠。最后子进程不在持有锁的时候,父进程不再block。
Win32用户可以在Cygwin下运行此代码。
评论
rubynroll
2008-01-03
这个只是我自己写的一个小工具而已,如有雷同,纯属偶然,呵呵~
你的lock文件和pid结合是个好办法。不过这个文件锁在程序异常退出的时候是会自动释放的(进程退出时所打开的所有文件会自动关闭)。当然我的程序没有处理异常也是不够健壮,改进后如下:
测试代码:
你的lock文件和pid结合是个好办法。不过这个文件锁在程序异常退出的时候是会自动释放的(进程退出时所打开的所有文件会自动关闭)。当然我的程序没有处理异常也是不够健壮,改进后如下:
=begin
file lock for inter-process sync.
usage:
FSLock('mylock') do
# protected by lock,
# do your job here ...
end
=end
class FSLock
def initialize(name=nil)
name ||= 'global'
@fname = name + '.lock'
if block_given?
lock()
begin
yield
ensure
unlock()
end
end
end
def critical
lock()
begin
yield() if block_given?
ensure
unlock()
end
end
def lock
@f = File.new(@fname, "ab")
@f.flock(File::LOCK_EX) if @f
end
def unlock
@f.close if @f
end
end
测试代码:
if $0 == __FILE__
unless fork
# child process
3.times do |i|
FSLock.new('/tmp/myapp') do
sleep 2 # child process sleep while holding the lock
puts "#{Time.now.to_s}: Ping !"
if i == 1
raise "Boom !"
end
end
end
else
# parent process
sleep 0.1
6.times do
FSLock.new('/tmp/myapp') do # parent process will be blocked while child holding the lock
puts "#{Time.now.to_s}: Pong !"
end
sleep 0.1
end
Process.wait
end
end
lgn21st
2008-01-02
原创?转贴? anyway,受教了
另外问个问题,如果block里面的代码执行中产生异常退出,导致僵尸锁文件,如何判断?
我自己用的办法是读取进程pid,然后将pid写入lock文件,如果启动新的进程,子进程时,会先查找这个lock文件,如果找到,读出pid,然后到“/proc”下面去找看有没有同名进程id,如果有则sleep,如果没有则将自己的pid写入lock文件中。
另外问个问题,如果block里面的代码执行中产生异常退出,导致僵尸锁文件,如何判断?
我自己用的办法是读取进程pid,然后将pid写入lock文件,如果启动新的进程,子进程时,会先查找这个lock文件,如果找到,读出pid,然后到“/proc”下面去找看有没有同名进程id,如果有则sleep,如果没有则将自己的pid写入lock文件中。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 4143 次
- 性别:

- 来自: Wgt

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
Ruby'陷阱'之: '||=' 的 ...
我之所以在这里“咬文嚼字”,是为了追求对语言的精确理解。 对于象ruby这种特 ...
-- by rubynroll -
Ruby'陷阱'之: '||=' 的 ...
geszJava 写道回复不见了? ruby按我说就是不断句的之乎者也,陷阱多多 ...
-- by seemoon -
Ruby'陷阱'之: '||=' 的 ...
回复不见了? ruby按我说就是不断句的之乎者也,陷阱多多,没多少前途。最终还是 ...
-- by geszJava -
SVN+GIT=鱼与熊掌兼得
干吗要那么麻烦呢,何不直接用 git-svn
-- by Lynx -
Ruby'陷阱'之: '||=' 的 ...
引用 但是David后来认为"a || a = b"应该更恰当些. 楼主是咬 ...
-- by seemoon






评论排行榜