My 1st question about locking (and other related issues)

Discussion in 'Perl Misc' started by Michele Dondi, Jun 30, 2004.

  1. I have a *working* .sig rotation script that begins like this:


    #!/usr/bin/perl

    use strict;
    use warnings;
    use POSIX;

    $|++;
    setsid;

    # ...
    # Do some administrative things like
    # redirecting STDIN STDOUT and STDERR
    # ...

    fork and exit;


    then it starts an infinite loop and writes to a fifo (creating it if
    it doesn't exist).

    Now I'd like to use some mechanism to prevent more than one copy of
    the program to run at the same time on the same machine. The named
    pipe is in my home, mounted on nfs.

    I've thought of using a lockfile, but then since I can be logged at
    the same time on different machines, I *think* I should write in it
    the hostname, possibly along with other info.

    Anyway, I've really *no* experience in these matters, so can you give
    me any suggestion? Also, I'm not asking you to do the job for me, but
    could you please provide some minimal code snippet?

    Note: I know I've read that file creation/deletion is not atomic over
    nfs, but I don't think this is really a major issue, since I'll call
    the script from my .bash_profile and it's hard to imagine how there
    could be race conditions...

    Last, I have another request: as I said above, I want to launch my
    script on login, and even if it wouldn't be a problem to have it
    running as a background process when I'm not logged in, I'd rather
    prefer to have it exit when I exit the shell.

    I know this is not strictly speaking a Perl question, but also in this
    case I'd welcome an actual code snippet.


    TIA,
    Michele
    --
    #!/usr/bin/perl -lp
    BEGIN{*ARGV=do{open $_,q,<,,\$/;$_}}s z^z seek DATA,11,$[;($,
    =ucfirst<DATA>)=~s x .*x q^~ZEX69l^^q,^2$;][@,xe.$, zex,s e1e
    q 1~BEER XX1^q~4761rA67thb ~eex ,s aba m,P..,,substr$&,$.,age
    __END__
     
    Michele Dondi, Jun 30, 2004
    #1
    1. Advertising

  2. Michele Dondi

    Anno Siegel Guest

    Michele Dondi <> wrote in comp.lang.perl.misc:
    > I have a *working* .sig rotation script that begins like this:
    >
    >
    > #!/usr/bin/perl
    >
    > use strict;
    > use warnings;
    > use POSIX;
    >
    > $|++;
    > setsid;
    >
    > # ...
    > # Do some administrative things like
    > # redirecting STDIN STDOUT and STDERR
    > # ...
    >
    > fork and exit;
    >
    >
    > then it starts an infinite loop and writes to a fifo (creating it if
    > it doesn't exist).
    >
    > Now I'd like to use some mechanism to prevent more than one copy of
    > the program to run at the same time on the same machine. The named
    > pipe is in my home, mounted on nfs.
    >
    > I've thought of using a lockfile, but then since I can be logged at
    > the same time on different machines, I *think* I should write in it
    > the hostname, possibly along with other info.


    I wouldn't write the hostname in the lockfile but name the lockfile
    after the host. In fact, you don't need explicit file locking,
    the existence of the lockfile can be used. The usual problem with
    this approach is to reliably remove the lockfile when the program
    terminates. %SIG handlers and an END block cover most of that.

    use Sys::Hostname;
    use Fcntl;

    my $lockdir = "$ENV{ HOME}/lockfiles";
    my $host = hostname;
    my $lockfile = "$lockdir/$host";
    sysopen my $lock, $lockfile, O_CREAT | O_EXCL, or
    die "$0 already running on $host";
    my $havelock = 1;
    END { unlink $lockfile if $havelock }
    $SIG{ $_} = sub { unlink $lockfile if $havelock } for
    qw( INT TERM); # add more signals if needed

    # rest of script
    # ...

    This ignores possible problems with NFS and atomic file operations.

    Anno
     
    Anno Siegel, Jul 1, 2004
    #2
    1. Advertising

  3. On 1 Jul 2004 09:53:22 GMT, -berlin.de (Anno
    Siegel) wrote:

    >> I've thought of using a lockfile, but then since I can be logged at
    >> the same time on different machines, I *think* I should write in it
    >> the hostname, possibly along with other info.

    >
    >I wouldn't write the hostname in the lockfile but name the lockfile
    >after the host. In fact, you don't need explicit file locking,
    >the existence of the lockfile can be used. The usual problem with
    >this approach is to reliably remove the lockfile when the program
    >terminates. %SIG handlers and an END block cover most of that.


    [snip code]

    Thank you so much for the supplied code, I really appreciated that! In
    fact I noticed that some other programs do something very similar...
    it still seems a bit of an overhead for such a simple script.

    I was wondering if there could be the possibility of using the named
    pipe itself to determine if there's already a copy of $0 running, i.e.
    trying to read from it and if nothing comes out in a certain amount of
    time (but then how much time?!?) then decide that it is not. Not
    terribly reliable, I guess, but... just curious about this
    possibility!

    Also, could you be so kind to answer my other question or give a
    suggestion just as good as this one wrt it? I mean: how can make my
    script exit on logging out of the shell from which it was started?


    TIA again,
    Michele
    --
    you'll see that it shouldn't be so. AND, the writting as usuall is
    fantastic incompetent. To illustrate, i quote:
    - Xah Lee trolling on clpmisc,
    "perl bug File::Basename and Perl's nature"
     
    Michele Dondi, Jul 1, 2004
    #3
  4. >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    AS> Michele Dondi <> wrote in
    AS> comp.lang.perl.misc:

    AS> I wouldn't write the hostname in the lockfile but name the
    AS> lockfile after the host. In fact, you don't need explicit
    AS> file locking, the existence of the lockfile can be used. The
    AS> usual problem with this approach is to reliably remove the
    AS> lockfile when the program terminates. %SIG handlers and an
    AS> END block cover most of that.

    Another approach would be to write the pid into the
    "lockfile". This would allow for the possibility of checking for
    stale lock files although I do not know of any good way to check
    for a process given a pid or verify it's the correct
    process (i.e. not another process that just happens to have
    inherited your pid).

    This also allows for a "kill" script in the .bash_logout that
    would open the "lockfile" and send an appropriate signal to the
    specified pid. Of course this is problematic for it would kill
    your sigfile "daemon" when the first shell exited. I presume you
    would want the "daemon" to continue until the last shell exited.

    What would be ideal (I think) is something like Debian's
    start-stop-daemon but this is not portable. You might look into
    your systems /etc/init.d/ scripts to see how daemons are started
    and stopped.

    AS> Anno

    --
    Dale Henderson

    "Imaginary universes are so much more beautiful than this stupidly-
    constructed 'real' one..." -- G. H. Hardy
     
    Dale Henderson, Jul 2, 2004
    #4
  5. On 01 Jul 2004 21:26:25 -0500, Dale Henderson <>
    wrote:

    > Another approach would be to write the pid into the
    > "lockfile". This would allow for the possibility of checking for
    > stale lock files although I do not know of any good way to check
    > for a process given a pid or verify it's the correct
    > process (i.e. not another process that just happens to have
    > inherited your pid).


    As a wild guess I'd say that this approach would tend to be more
    complicated than that suggested before, but indeed I've seen something
    along these lines...

    > This also allows for a "kill" script in the .bash_logout that
    > would open the "lockfile" and send an appropriate signal to the
    > specified pid. Of course this is problematic for it would kill
    > your sigfile "daemon" when the first shell exited. I presume you
    > would want the "daemon" to continue until the last shell exited.


    Well, I think that *if* I have a duplicate processes prevention
    mechanism *and* if it continues until the shell it was started from is
    exited, *then* that shell will be "the last to be exited".

    > What would be ideal (I think) is something like Debian's
    > start-stop-daemon but this is not portable. You might look into
    > your systems /etc/init.d/ scripts to see how daemons are started
    > and stopped.


    My distro (here at home, at University we/they use Gentoo) is very
    KISS-oriented (CRUX, available at <http://crux.nu>). As an example the
    gpm daemon script (which I wrote myself modelling it after the ones
    shipped with the distro) is as follows:

    #!/bin/sh
    #
    # /etc/rc.d/gpm: start/stop gpm daemon
    #

    case $1 in
    start)
    modprobe -q psmouse
    /usr/sbin/gpm -m /dev/misc/psaux -t ps2
    ;;
    stop)
    /usr/sbin/gpm -k || killall -q /usr/sbin/gpm
    ;;
    restart)
    $0 stop
    sleep 2
    $0 start
    ;;
    *)
    echo "usage: $0 [start|stop|restart]"
    ;;
    esac

    # End of file


    Michele
    --
    you'll see that it shouldn't be so. AND, the writting as usuall is
    fantastic incompetent. To illustrate, i quote:
    - Xah Lee trolling on clpmisc,
    "perl bug File::Basename and Perl's nature"
     
    Michele Dondi, Jul 3, 2004
    #5
  6. >>>>> "MD" == Michele Dondi <> writes:

    MD> On 01 Jul 2004 21:26:25 -0500, Dale Henderson
    MD> <>
    MD> wrote:

    >> Another approach would be to write the pid into the
    >> "lockfile". This would allow for the possibility of checking
    >> for stale lock files although I do not know of any good way to
    >> check for a process given a pid or verify it's the correct
    >> process (i.e. not another process that just happens to have
    >> inherited your pid).


    MD> As a wild guess I'd say that this approach would tend to be
    MD> more complicated than that suggested before, but indeed I've
    MD> seen something along these lines...

    Unfortunately it would be MUCH more complicated.


    >> This also allows for a "kill" script in the .bash_logout that
    >> would open the "lockfile" and send an appropriate signal to the
    >> specified pid. Of course this is problematic for it would kill
    >> your sigfile "daemon" when the first shell exited. I presume
    >> you would want the "daemon" to continue until the last shell
    >> exited.


    MD> Well, I think that *if* I have a duplicate processes
    MD> prevention mechanism *and* if it continues until the shell it
    MD> was started from is exited, *then* that shell will be "the
    MD> last to be exited".

    I don't follow this. Consider:

    Shell 1 starts (daemon starts)

    Shell 2 starts

    Shell 1 exits (daemon stops)

    Shell 2 exits

    So the daemon stops with shell 1 but shell 2 is the last to exit.


    --
    Dale Henderson

    "Imaginary universes are so much more beautiful than this stupidly-
    constructed 'real' one..." -- G. H. Hardy
     
    Dale Henderson, Jul 3, 2004
    #6
  7. On 03 Jul 2004 16:22:25 -0500, Dale Henderson <>
    wrote:

    > MD> Well, I think that *if* I have a duplicate processes
    > MD> prevention mechanism *and* if it continues until the shell it
    > MD> was started from is exited, *then* that shell will be "the
    > MD> last to be exited".
    >
    > I don't follow this. Consider:
    >
    > Shell 1 starts (daemon starts)
    >
    > Shell 2 starts
    >
    > Shell 1 exits (daemon stops)
    >
    > Shell 2 exits
    >
    > So the daemon stops with shell 1 but shell 2 is the last to exit.


    Uh-Oh!!! Was I missing something hugely obvious? Yes, definitely I
    was...


    Michele
    --
    you'll see that it shouldn't be so. AND, the writting as usuall is
    fantastic incompetent. To illustrate, i quote:
    - Xah Lee trolling on clpmisc,
    "perl bug File::Basename and Perl's nature"
     
    Michele Dondi, Jul 4, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Dalberg
    Replies:
    0
    Views:
    446
    John Dalberg
    Oct 6, 2003
  2. Maxwell Hammer
    Replies:
    7
    Views:
    673
    Peter Hansen
    Jun 18, 2005
  3. Timasmith
    Replies:
    4
    Views:
    488
    Bjorn Borud
    Nov 1, 2006
  4. John Dalberg
    Replies:
    2
    Views:
    261
    John Dalberg
    Oct 7, 2003
  5. Walle Wallen
    Replies:
    1
    Views:
    107
    Brian Candler
    Jan 15, 2011
Loading...

Share This Page