How To: Non-Blocking Semaphore Access in PHP
By pratima, Gaea News NetworkTuesday, June 3, 2008
Semaphore is used to restrict access to shared resources, such as shared memory or to limit the number of processes that may simultaneously use a resource, in a multi-process or multi-threaded environment.
In php using semaphore a process must wait while accessing a shared resource currently used by another process. But this may not be required for all cases. Sometimes we need to just verify whether a resource has been locked and move on. Unfortunately we have no way to check the status of a semaphore lock in php. Let’s see how we can implement non-blocking semaphore access in PHP.
As the semaphore library doesn’t give us what we need we will have to use file existence as a lock instead. The concept and implementation is simple:
1. Before accessing a shared resource you have to check whether a pre-determined file (say .lock ) exists and file modification time doesn’t exceed a fixed (configurable) expire time. The second condition is required to recover from old locks which haven’t been cleared due to abrupt termination of the previous process or other reasons.
2. If either of the condition is not satisfied in step 1 then create or modify the lock file and use the shared resource. After you are done, you must delete the lock file to allow subsequent access of the shared resource. The deleting must be done irrespective of any error condition in earlier stages by proper exception / error handling of earlier steps to prevent abrupt termination.
3. If both the conditions are satisfied then the resource has been locked and not available currently. Now you can either wait and check periodically in a loop with sleep or move on to next tasks.
Let look at how we can implement this with sample code:
if(file_exists(".lock") && ((time() - filemtime(".lock")) < 1800)) {
// The resource is locked. You can either move on to next tasks or wait and check periodically in a loop
} else {
@touch(".lock");
// Use shared resource here
// Ideally this should be done after error handling in previous steps,
// so no errors caused above can prevent execution of this step.
@unlink(".lock"); // Release the lock
}
January 28, 2009: 4:00 am
Hi, I was wondering about the thread safety. If two processes check the file status at the same time (or actually in succession of eachother) they will both acquire access, touch the file and then have access to the critical resource. Am I missing something? Regards |
Mark