Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,

I found a snippet at this node for checking if an instance of a program is running. It seems to work fine, killing a second instance of the program, but I expected the error message "Already executing: $!"; to appear. However, the error message doesn't display. Whats going on? and how can I get the error message to display?
#!/usr/bin/perl use Fcntl qw(LOCK_EX LOCK_NB); flock DATA, LOCK_EX | LOCK_NB or die "Already executing: $!"; my $maxprimes=200; #Stop when you've found this many my $value=1; my $count=0; while ($count < $maxprimes){ $value++; my $composite=0; OUTER: for (my $i=2; $i<$value; $i++){ for (my $j=$i; $j<$value; $j++){ if (($j*$i)==$value){ $composite=1; last OUTER; } } } if (! $composite){ $count++; print "$value "; } } # do not remove this __END__ __END__
Thanks in advance,
Jonathan

Replies are listed 'Best First'.
Re: error message not working
by Arunbear (Prior) on Nov 30, 2004 at 12:09 UTC
    On win32, ActivePerl 5.8.4, the 2nd process dies without the error message. I changed
    flock DATA, LOCK_EX | LOCK_NB or die "Already executing: $!";
    to
    open my $dummy, ">lock" or die $!; flock $dummy, LOCK_EX | LOCK_NB or die "Already executing: $!";
    and then I did get the error message:
    Already executing: Domain error at temp2.pl line 7.
      Ah yes. On some operating systems, you can only do a LOCK_EX on a handle that's open for writing. DATA is open for reading only. I guess that is why the original fails, and your version works.

      Update: perldoc -f flock has this to say about it:

      Note that the emulation built with lockf(3) doesn't provide shared locks, and it requires that FILEHANDLE be open with write intent. These are the semantics that lockf(3) implements. Most (all?) systems implement lockf(3) in terms of fcntl(2) locking, though, so the differing semantics shouldn't bite too many people.
      That must be the case, here. "Not too many people", right.
      does this open an actual file?
      what I was trying to do was open DATA (after __END__) to ensure that the actual script wasn't already being run. I was trying to get Merlyn's snippet from the node I mentioned above to work for me, it does work apparently, but not on windows...
      Any advise appreciated
      Jonathan
        It does open an actual file. I know what you are trying to do. I'm only suggesting it as a work-around because opening DATA isn't doing the job on win32. As I showed before, using a real sentinel file does prevent additional instances of the script from running. merlyn suggested opening DATA because the code is simpler that way.
Re: error message not working
by Happy-the-monk (Canon) on Nov 30, 2004 at 11:57 UTC

    perldoc -f flock says:

    Two potentially non-obvious but traditional
    "flock" semantics are that it waits indefinitely
    until the lock is granted, ...

    So it works alright it seems, it just waits until it will be allowed to flock the file instead of aborting with that error message.

    Cheers, Sören

      Actually no, it doesn't, because of the LOCK_NB, flock won't block but returns immediately. Of course, this only works on *nix-like systems, not on windows-like ones, so I'm guessing that's where the problem is.
Re: error message not working
by fglock (Vicar) on Nov 30, 2004 at 11:57 UTC

    It works here (Linux). What's your operating system, Perl version?

      I'm running on windows 2000, with Activestate perl v5.8.4
      So if it works on Linux, how can I get the same thing to work on windows? Thanks,
      Jonathan

        First find a Linux CD . . .

        :)

Re: error message not working
by ikegami (Patriarch) on Nov 30, 2004 at 18:29 UTC

    Microsoft suggestes that you use the OS's named Semaphores. Win32::Semaphore, which comes with ActiveState, gives you access to those. You could decide whether to use semaphores or flock based on $^O. Be sure to provide a $name argument!!