| File::Lock::Multi - Lock files more than once |
File::Lock::Multi - Lock files more than once
use File::Lock::Multi::Fuser;
my $lock = File::Lock::Multi::Fuser->new(file => "/path/to/file", max => 3);
$lock->lock or die; # no more than 3 locks have been taken out on "/path/to/file" [...]
flock() (and co-operative locks in general) are a handy tool used for various synchronization tasks;
POSIX supports the concept of "exclusive" ("write") and "shared" ("read") locks on files -- many processes may take out a "shared" lock on any particular file, but only one process may have an "exclusive" lock, and that process can not take out this lock unless there are no "shared" locks open.
Part of what makes this such an effective and worry-free system, is that these locks are maintained on the kernel level -- so if you kill off a process, you do not need to be concerned that the locks it had will stick around and get in some other process's way.
... But let's say you have a CPU-intensive operation that you want to limit to, oh, 5 running copies at a time? Or 3 different types of CPU-intensive operation that you want to collectively limit to 2 running copies at a time? You could keep a counter somewhere, but if processes are killed off manually, what is going to come along and decrement your counter?
"exclusive" locks are just that -- exclusive -- and there is no simple way to tell how many processes have taken out a "shared" lock on a file (from perl, anyway).
File::Lock::Multi is designed to work around this problem by providing
it's own type of "locks" that behave like POSIX "exclusive" locks, except
that you can specify how many locks are allowed to be taken out. So long
as each process agrees on the maximum number of locks, they can work in
parallel, but within the limits you have specified.
There are currently two locking mechanisms available;
the File::Lock::Multi::Fuser manpage allows you to have multi-locks using just
one file, but only works on linux and has some drawbacks (see the
documentation for details); the File::Lock::Multi::FlockFiles manpage uses
the flock() call on several files named after the file you specify
in order to emulate allowing more than one lock.
Creates a new File::Lock::Multi object, which will represent a lock
on a file. Once you have an object, you can attempt to aquire a lock
with the "lock" method; the lock will be relinquished when you call
the "release" method, or when the object falls out of scope.
Note that you cannot call new directly on File::Lock::Multi, you
must do so on a particular implementation such as
the File::Lock::Multi::Fuser manpage or the File::Lock::Multi::FlockFiles manpage
"new" takes the following parameters; only "file" is required:
The name of the file you wish to lock; this parameter is required. If the file does not already exist, a zero-byte file will be created when you attempt to acquire the lock with lock.
This parameter is required.
The maximum number of lockers that may lock this file.
Default: 1
How long to wait to acquire the lock, in seconds. A value of zero means don't wait at all, and a negative value means to wait forever (block).
Default: -1 (wait forever).
How often to check if the lock is available when waiting, in seconds.
For example, if "timeout" was set to "5", and "polling_interval" was
set to "0.5", File::Lock::Multi would try to obtain the lock
every half a second, up to a maximum of five seconds, before giving up.
Default: 0.2 (1/5th of a second).
lock([$timeout])
Acquire a lock, obeying timeout and polling_interval above. Returns a true value on success, or a false value if the the lock could not be acquired in time.
This method actually works by taking out the lock anyway, and then checking if there are too many lockers -- if there are too many lockers, it releases the lock, and optionally waits for polling_interval and tries again.
If $timeout is specified, this overrides the object's default.
Returns a true value if an attempt to take out the lock would succeed. This method works by calling lock with a timeout of zero (non-blocking), then immediately releases the lock if it obtained one.
Returns true if this lock is active, false otherwise.
Release a lock if we have taken one out. Raises an exception if we have not.
Returns an array with an entry for each entity that has locked this file. Presumedly each entry in the array is some sort of identifier indicating _who_ has locked this file, but that would be implementation specific. :-)
For the original idea.
For keeping the munchkins happy and occupied while I worked on this.
Copyright 2009 Tyler "Crackerjack" MacDonald <japh@crackerjack.net>
This is free software; You may distribute it under the same terms as perl itself.
the File::Lock::Multi::Fuser manpage for technical details about the linux /proc implementation.
the File::Lock::Multi::FlockFiles manpage for technical details about the multiple-file implementation.
the IPC::Locker manpage for a network-based locking solution that kind-of supports the same thing via an internet daemon ("Multiple locks may be requested, in which case the first lock to be free will be used.")
| File::Lock::Multi - Lock files more than once |