tags:

views:

104

answers:

2

A SO user asked a question to which the answer effectively was "use a locking mechanism".

While researching my answer, I discovered that there seems to be no simple, inter-process-reliable locking mechanism in PHP. flock() has a big fat warning:

On some operating systems flock() is implemented at the process level. When using a multithreaded server API like ISAPI you may not be able to rely on flock() to protect files against other PHP scripts running in parallel threads of the same server instance!

The discussion in this question delves into the issue pretty deeply, but comes up only with rather complex solutions: Using a RAM disk, or Memcache.

The only thing that looks halfway good is mySQL's GET_LOCK().

So my question is: Is this really the way it is? Is there really no simple, straightforward, cross-platform safe locking system in PHP? One that is atomic, and will release the lock if the owner process dies, and doesn't need huge setup efforts?

+1  A: 

PHP is not meant as a permanent process but more as a short term lived thread in the sense that it's created and destroyed often. Depending on the implementation, it more than one PHP process may run at the same time on the same code.

I believe that the various PHP implementation (mod_php, PHP CLI, etc.) make locking and threads difficult in PHP.

Wernight
True, that is the current situation. However, not only permanently running processes need locking - it's a pretty common requirement, e.g. to prevent race conditions. I'm hoping to learn of some sort of standard locking library that makes this half-way easy.
Pekka
+1  A: 

Disagree with Wernight's answer. Yes the web stuff is very relevant - but the limiting factor is how the OS behaves.

On all the OS supported by PHP there are only 2 choices for file locking - blocking or non-blocking. Ultimately PHP must use the OS file-locking mechanism to avoid conflicts with non-PHP code accessing te same files. If you use blocking locks, then the PHP script may be blocked indefinitely waiting for the lock to be released - not a good scenario for a web application. OTOH if you make a non-blocking lock call and it fails - what do you do next - do you just wait a random amount of time and let all your PHP scripts try to grab the lock?

The only practical way to solve the problem is with a queued lock request which times out - but AFAIK there's no OS natively providing that facility. I've written such code myself - for a dedicated webserver so there was no problem with allowing other programs access, however I expect that it may be possible to extend to a system-wide mandatory locking system using inotify.

symcbean