浏览 2926 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-12-29
=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下运行此代码。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-01-02
原创?转贴? anyway,受教了
另外问个问题,如果block里面的代码执行中产生异常退出,导致僵尸锁文件,如何判断? 我自己用的办法是读取进程pid,然后将pid写入lock文件,如果启动新的进程,子进程时,会先查找这个lock文件,如果找到,读出pid,然后到“/proc”下面去找看有没有同名进程id,如果有则sleep,如果没有则将自己的pid写入lock文件中。 |
|
返回顶楼 | |
发表时间:2008-01-03
这个只是我自己写的一个小工具而已,如有雷同,纯属偶然,呵呵~
你的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 |
|
返回顶楼 | |