http://qs1969.pair.com?node_id=1008652

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

I have a program, where several instances run concurrently. They platforms to be supported are: Windows XP, Windows 2003 Server, Windows 2008 Server, and Windows 7 (64 Bit).

These processes 'share' a piece of code which should be executed as a critical region, i.e. only one of the processes is supposed to execute this part of the code at any time. To implement this, I use flock on a lockfile to guard entry and exit to the critical region, i.e. I basically do a

sysopen(LOCKFILE,$lockfile,O_WRONLY|O_CREAT); while(!flock(LOCKFILE, LOCK_EX|LOCK_NB)) { sleep($some_random_time); } ######################### # CRITICAL REGION IS HERE ######################### flock(LOCKFILE, LOCK_UN); close(LOCKFILE);
This works well. Now I wonder: Could there be cases, where a process gets killed while being in the critical region, BUT the lock is not being released (and therefore all other processes would be locked out forever)?

I wrote a small test program to research this case, but no matter how I killed the process holding the lock, the lock was always freed afterwards. Of course this doesn't mean that what I'm doing is safe. It just means that I was not able to break it.

Could someone with good experience in Windows programming give me some enlightment here?
-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: flock on Windows : process killed while in critical region
by BrowserUk (Patriarch) on Dec 13, 2012 at 12:27 UTC
    Now I wonder: Could there be cases, where a process gets killed while being in the critical region, BUT the lock is not being released (and therefore all other processes would be locked out forever)?

    In a nutshell: No, that cannot happen.

    However, if a process terminates whilst holding a lock, it may be some time before the OS gets around to releasing the lock -- dependent upon the availability of suitable system resources -- so attempts to acquire the lock should be programmed to retry, without tight loop polling, as a tight polling loop can itself be the cause of the unavailability of those system resources.

    (For more info, see the "Remarks" under LockFile(Ex)(), which is the system call that underlies perl's emulation of flock() on Windows.)


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    RIP Neil Armstrong

      Thanks, I'm relieved - this makes implementation simpler. As for no tight loop polling: I guess a sleep time of a couple of seconds between two calls to flock would not be considered tight anymore, i.e. it would be safe? Currently, we usually sleep between 3 and 12 seconds between polls.

      -- 
      Ronald Fischer <ynnor@mm.st>
        I guess a sleep time of a couple of seconds between two calls to flock would not be considered tight anymore, i.e. it would be safe?

        Even half a second or just sleep 0 (which causes the process to relinquish it's current timeslice) will ensure the OS gets processor time to clean up the dying process.

        The situation where things go wrong is when you have multiple processes all polling in tight loops, thus not giving the (lower priority) task of cleaning up the terminating process a look in.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        RIP Neil Armstrong

Re: flock on Windows : process killed while in critical region
by BrowserUk (Patriarch) on Dec 13, 2012 at 12:38 UTC

    As an aside, if your program is only targeting Windows, Win32::Mutex provides a simpler, safer and more efficient means of serialising access to shared resources across processes.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    RIP Neil Armstrong

Re: flock on Windows : process killed while in critical region
by flexvault (Monsignor) on Dec 13, 2012 at 15:37 UTC

    Hello rovf,

    I believe the unlock is optional in your code. Closing the file automatically frees the lock. So if a script were to die during the critical code, then the lock would be freed as part of closing all files by Perl.

    ######################### # CRITICAL REGION IS HERE ######################### flock(LOCKFILE, LOCK_UN); ## optional close(LOCKFILE);

    I did a 'super-search' and found this quote but not the slides that are mentioned. "...Check out the links to Dominus' File Locking Tricks and Traps slides in the Question about Flock and die thread for more details..." by converter.

    For several years, I would go through the slides again, since 'flock' is very powerful and easy to forget all the "tricks" that can be used. My bookmark didn't work, so maybe the slides have been moved.

    Have a good one...Ed

    "Well done is better than well said." - Benjamin Franklin