16

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?

Community
  • 1
  • 1
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 5
    I normally abuse [`lockfile`](http://linux.about.com/library/cmd/blcmdl1_lockfile.htm), but that's hardly a _PHP_ solution. – Wrikken Oct 21 '10 at 17:47
  • @Wrikken yeah, it would be nice to have a portable generic way. But good tip anyway – Pekka Oct 21 '10 at 17:48
  • Perhaps there is a distributed-locking store/cache you can use instead. –  Oct 21 '10 at 18:49
  • Using GET_LOCK or memcache are pretty straight forward, and I've never had any problems using either technique for locking on large sites. – mellowsoon Oct 21 '10 at 21:04
  • @mellowsoon yeah, but they both bring a pretty large dependency. I would like to know whether there is anything independent (it may well be that there is not). Anyway, that is good to know – Pekka Oct 21 '10 at 21:05
  • @Pekka - It is a drag that there's no real way to do it easily. – mellowsoon Oct 21 '10 at 21:27

2 Answers2

3

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
  • 47,736
  • 6
  • 59
  • 94
1

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
  • 36,122
  • 25
  • 118
  • 131
  • 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 Oct 22 '10 at 15:11