|Perl: the Markov chain saw|
Ensuring only one copy of a perl script is running at a timeby eyepopslikeamosquito (Bishop)
|on Dec 19, 2006 at 07:49 UTC||Need Help??|
eyepopslikeamosquito has asked for the wisdom of the Perl Monks concerning the following question:
A workmate asked me the best way to ensure that only one copy of his Perl script is running at a time. From a quick SuperSearch, a couple caught my eye:
I was intrigued by the adamk trick, so tested it with:
This works fine on Unix. On Windows, however, instead of exiting with a nice "already running" message, the perl script surprised me by printing nothing and exiting immediately with an exit code of zero (this is the same perplexing behaviour reported by BrowserUk in Re: Why no LockFile() in Win32API::File ?).
Stepping through the code in the debugger reveals the root cause of this odd behaviour. When the file is locked on Windows, you can open it ok but you get an error when you attempt to read from it. Now, the lower layers of the Perl IO system detect the read error all right (setting PerlIOBase(f)->flags |= PERLIO_F_ERROR), but the first PerlIO_getc() call in Perl_sv_gets() returns EOF ... so perl dutifully parses and runs an empty file, which explains why nothing happens and you get an exit code of zero.
So, being pressed for time, I suggested this variation on adamk's cute trick:
Though this simple solution seems sound to me, it is easy to overlook subtle problems and race conditions. So if anyone can see a flaw in this solution or has any other advice, please respond away.
Update: the above test program still seems to work the same way today (2020). See also: