Daniel Berger
5/28/2008 6:33:00 PM
On May 25, 7:46=A0am, "Sean O'Halpin" <sean.ohal...@gmail.com> wrote:
> On Wed, May 21, 2008 at 5:25 AM, DanielBerger<djber...@gmail.com> wrote:
> > Hi all,
>
> > I'm probably late to the game on this, but I stumbled across an
> > interesting use for DATA. You can use it to ensure only one instance
> > of a given script is running by using flock:
>
> > class Foo
> > =A0 def self.mainloop
> > =A0 =A0 =A0while true
> > =A0 =A0 =A0 =A0 puts "Looping..."
> > =A0 =A0 =A0 =A0 sleep 3
> > =A0 =A0 =A0end
> > =A0 end
> > end
>
> > DATA.flock(File::LOCK_EX)
>
> > if $0 =3D=3D __FILE__
> > =A0 Foo.mainloop
> > end
>
> > __END_
>
> > The first run will work, but trying to start the program up again will
> > fail instantly because of the lock on DATA. I should probably do some
> > cleanup there, too, but I thought I'd toss this out there and see if
> > this is of interest to anyone.
>
> > Or was I was recovering from a hangover in college when they mentioned
> > this trick in class? Anyway, there you go.
>
> > Regards,
>
> > Dan
>
> Nice one! However, I don't get a failure (on Linux) - instead the
> second instance blocks waiting for the first instance to terminate at
> which point it executes. Also, needing to specify __END__ is a little
> awkward IMHO.
>
> I wonder, does the following work on Windows?
>
> if $0 =3D=3D __FILE__
> =A0 if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
> =A0 =A0 Foo.mainloop
> =A0 end
> end
>
> Wrapped up in a method:
>
> $ cat single_instance.rb
> def single_instance(&block)
> =A0 if File.open($0).flock(File::LOCK_EX|File::LOCK_NB)
> =A0 =A0 block.call
> =A0 else
> =A0 =A0 warn "Script #{ $0 } is already running"
> =A0 end
> end
>
> $ cat self_locking.rb
> require 'single_instance'
> if __FILE__ =3D=3D $0
> =A0 single_instance do
> =A0 =A0 Foo.mainloop
> =A0 end
> end
Yep, that's definitely cleaner, thanks.
> I think I'll use this :)
Excellent. Good to know someone found it useful. :)
Regards,
Dan