How to pass lock to the parent process?

  • Thread starter Hallvard B Furuseth
  • Start date
H

Hallvard B Furuseth

I need a to pass a file lock to the parent process - and
to detect that this works.

The best answer would be passing a file descriptor through a socket, but
I couldn't find how to do that with Perl.

Another way is to open() the file in the parent and flock() it in the
child - that works on my host, but I don't know how to test reliably if
it works. Perl can use either the C system call flock(), lockf() or
fcntl() for file locks, and I don't even know if it is reliable for the
flock() system call.

use Fcntl qw:)flock);
open(LK, "+>/tmp/foobar.lock") or die;
unless (fork()) {
# Child
flock(LK, LOCK_EX) or die;
exit(0);
}
# Parent
wait; die if $?;
# LK is locked
 
X

xhoster

Hallvard B Furuseth said:
I need a to pass a file lock to the parent process - and
to detect that this works.

Why? If the parent needs the lock, why not have the parent lock it?

Xho
 
H

Hallvard B Furuseth

Why? If the parent needs the lock, why not have the parent lock it?

Well, that's another way. But there are several children. Each should
start processing as soon as its lock can be acquired. I don't want to
need to go through the whole program to make it thread-safe, so the
parent can just wait for one file lock at a time - at least if it uses
flock().
 
H

Hallvard B Furuseth

I said:
Well, that's another way. But there are several children. Each should
start processing as soon as its lock can be acquired. (...)

Oops, that was a fine example of a too-late-night posting:)

The other half of the answer is that the client first does some work,
and after that it may need the lock for some more work. After that it
may need to ask the parent to take over.

There are various ways to achieve that, but the simplest way - when
available - is for the child to create the lock and pass it to the
parent.
 
X

xhoster

Hallvard B Furuseth said:
Well, that's another way. But there are several children. Each should
start processing as soon as its lock can be acquired. I don't want to
need to go through the whole program to make it thread-safe, so the
parent can just wait for one file lock at a time - at least if it uses
flock().

You can use a non-blocking flock. This would require a polling loop, but
it shouldn't be too bad. It should be localizable to just one part of the
code, with little impact elsewhere.


Xho
 
X

xhoster

Hallvard B Furuseth said:
I need a to pass a file lock to the parent process - and
to detect that this works.

The best answer would be passing a file descriptor through a socket, but
I couldn't find how to do that with Perl.

Have you looked at File::FDpasser?

Another way is to open() the file in the parent and flock() it in the
child - that works on my host, but I don't know how to test reliably if
it works. Perl can use either the C system call flock(), lockf() or
fcntl() for file locks, and I don't even know if it is reliable for the
flock() system call.

I'm not confident that any method is gauranteed to work across all these
variations. Is your goal to have something that works for your system, and
it would be nice if it is portable? Or is the goal to have something that
must be portable?

Xho
 
A

A. Sinan Unur

Oops, that was a fine example of a too-late-night posting:)

The other half of the answer is that the client first does some work,
and after that it may need the lock for some more work. After that it
may need to ask the parent to take over.

Honestly, I would like to take a stab at answering this question, but
you make it unnecessarily hard to help you by not providing concrete
information.

Please post a short but complete script illustrating what you want to
do, and explain how it does not do what you want to do. The posting
guidelines explain how to compose a message that will give you the
greatest chance of getting a useful response.

Sinan
 
H

Hallvard B Furuseth

Have you looked at File::FDpasser?

Perfect! Thanks!
I'm not confident that any method is gauranteed to work across all
these variations. Is your goal to have something that works for your
system, and it would be nice if it is portable?

Yes. And to make sure, it must reliably return an error when it doesn't
work. The problem which needs these locks will likey be obsolete by the
time I need to do any porting. (So the hack I posted at first would
also be OK, if I knew how to ask Perl if it works.)
 
H

Hallvard B Furuseth

Purl said:
(...)

Use a semaphore lock. This type of lock can be verified, independently,
by a parent process or any number of child processes. However, you must
code a "fail-safe" method to release a semaphore lock.

Thanks. I didn't even remember that they can be associated with files
so they can be used as file locks. I really need to learn to work with
semaphores. They seem to have some quirks, like clean-up, so I've
avoided them so far.

Anyway, I'll use File::FDpasser for now, and add a note to look at
semaphores someday if needed.
Appears you are working with a race condition. If so, all of your
processing should be performed by a single program. Use of forking
will only increase chances of file corruption and increase chances of
program failure.

It's a race condition between different instances of that program -
which runs regularly from cron but is also sometimes invoked by hand.

Someday I'll axe to the whole messy thing and start over. Then it could
be rewritten as a daemon which one can talk to over a socket, but for
now I'll just add the necessary updates and clean up a bit.
What you describe in your articles makes little sense. You will do
better to provide readers with a clear, concise and coherent
description.

Well, I hoped the initial techincal question would be enough. Which it
was, as it turns out:)
 
X

xhoster

Hallvard B Furuseth said:
Perfect! Thanks!


Yes. And to make sure, it must reliably return an error when it doesn't
work. The problem which needs these locks will likey be obsolete by the
time I need to do any porting. (So the hack I posted at first would
also be OK, if I knew how to ask Perl if it works.)

I'm not sure what you mean by "works". If the child fails to obtain the
lock, it should die or do something else such that $? in the parent is not
zero.

If you need to know if the lock on a forked fh (by the child) survives in
the parent after the child's demise, do a test to determine that. This is
a property of the system, not of a race condition or something. So if it
works on your system, it works. You don't need to test it each time you
run the program, only each time you make major changes to your system.

perl -le 'fork; open $fh, ">foo" or die $!; fork or do {flock $fh,2 or die
$!;\ warn "$$ Got lock"; exit}; sleep 20; warn "$$ releasing lock"'

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top