![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
King of Portal
|
File Locking without using flock
Any ideas?
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#2 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5
![]() |
Re: File Locking without using flock
Depends what you're trying to achieve.
One option would be to generate a temporary file name using a process that guarantees a unique name so it is only known to the process/script that generates it. Then rename/move the file you want to that temporary location. The file is effectively locked, as (in the eyes of any other processes) it no longer exists. Then do all your work on the temporary file. When the work is done rename/move the temporary file back to the original location. Depending on needs of the application, check if the original file has been recreated while work has been done on the temporary file -- and respond in a manner that makes sense to your script (eg append the original file to the temporary and delete it before copying the whole lot back, etc) Another option is to use specific features of your operating system to enforce locks in different ways. The trade-off there is that the script is no longer portable. Yet another option is to implement your system in a client/server arrangement, and (as far as your script is concerned) do without files completely. The script communicates with some back-end server (eg a database) which mediates access to the data via (say) a transactional approach. |
|
|
|
|
|
#3 |
|
King of Portal
|
Re: File Locking without using flock
The second and third option would not be viable as my forum script needs to remain portable and no client/server communication is necessary. What I'm trying to achieve is a database that locks files so as to prevent accidental overwriting.
This is what I understood in a stepwise fashion:
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#4 |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,198
Rep Power: 5
![]() |
Re: File Locking without using flock
Yes, randomly generated names can clash. One way to reduce likelihood is to check the existence of the randomly named file and, if it exists, generate another name. There are many ways to generate random names; I'll leave learning such things as an exercise.
Also, look up the tempnam() function. Names generated are not necessarily random, but they are specified as unique. Your requirement for portability and guaranteed file locking, in general, are mutually exclusive. True file locking (preventing access by anything except the creator) relies on support of the host operating system, so always inherently has some element of non-portability (and not all systems can do it). Why, if you are essentially looking for database-like behaviour, is it not suitable to use a database back end? There are a number of portable (or, more correctly, multiplatform) database products around. |
|
|
|
|
|
#5 |
|
King of Portal
|
Re: File Locking without using flock
I'm trying to develop a database backend using flat files ^_^. At the moment I believe my database creates files which will never overwrite one another. However, I just want to check other options available as perhaps one will appear as superior.
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#6 |
|
King of Portal
|
Re: File Locking without using flock
Dude that tempnam function is sweet grumpy that seems to be exactly what I was looking for. Now I just need to figure out a way to rename the files without accidentally overwriting another one.
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#7 |
|
King of Portal
|
Re: File Locking without using flock
This is the solution I came up with thx to grumpy's suggestions and some research into mutex and such to get a lock on a file without actually using the flock function.
function mutexAcquireLock($filename, $timeout){
$fp = @fopen($filename . '.lck', 'x');
if($fp === false) return false;
if(false === @fwrite($fp, time() + $timeout)) return false;
return fclose($fp);
}
function mutexReleaseLock($filename){
return @unlink($filename . '.lck');
}
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#8 | ||
|
King of Portal
|
Re: File Locking without using flock
Here were the results of two simultaneous scripts (mutex.php and tester.php) running on windows attempting to lock the file mutex.php
mutex.php results Quote:
Quote:
mutex.php <?php
for($i = 0; $i < 10; $i++){
fwrite(STDOUT, getmypid() . ": ");
if(!mutexAcquireLock('mutex.php', 2)){
fwrite(STDOUT, "Failed lock\n");
sleep(2);
}else{
fwrite(STDOUT, "Lock acquired -> ");
if(!mutexReleaseLock('mutex.php')){
fwrite(STDOUT, "File not locked" . "\n");
}else{
fwrite(STDOUT, "Lock released" . "\n");
}
sleep(2);
}
}
function mutexAcquireLock($filename, $timeout){
$fp = @fopen($filename . '.lck', 'x');
if($fp === false) return false;
if(false === @fwrite($fp, time() + $timeout)) return false;
return fclose($fp);
}
function mutexReleaseLock($filename){
return @unlink($filename . '.lck');
}
?><?php
for($i = 0; $i < 20; $i++){
fwrite(STDOUT, getmypid() . ": ");
if(!mutexAcquireLock('mutex.php', 2)){
fwrite(STDOUT, "Lock failed -> ");
$tiempo = mutexTimeOut('mutex.php');
if($tiempo !== false && $tiempo < 0){
if(!mutexReleaseLock('mutex.php')){
fwrite(STDOUT, "Unable to forcibly remove lock" . "\n");
}else{
fwrite(STDOUT, "Lock forcibly removed" . "\n");
}
}
sleep(1);
}else{
fwrite(STDOUT, "Lock acquired -> ");
if($i != 10){
if(!mutexReleaseLock('mutex.php')){
fwrite(STDOUT, "File not locked" . "\n");
}else{
fwrite(STDOUT, "Lock released" . "\n");
}
}else{
sleep(5);
}
sleep(1);
}
}
function mutexAcquireLock($filename, $timeout){
$fp = @fopen($filename . '.lck', 'x');
if($fp === false) return false;
if(!@chmod($filename . '.lck', 0755)) return false;
if(false === @fwrite($fp, time() + $timeout)) return false;
return fclose($fp);
}
function mutexReleaseLock($filename){
return @unlink($filename . '.lck');
}
function mutexTimeOut($filename){
$timeout = @file_get_contents($filename . '.lck');
if($timeout === false) return false;
return intval($timeout) - time();
}
?>
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
||
|
|
|
|
|
#9 |
|
King of Portal
|
Re: File Locking without using flock
I did realize there would be one flaw where if the system hanged, it's possible that another script could override the lock, then the process that was hanging could reengage and overwrite as it deems that it never released the lock. In order to compensate for that I made the timeout a factor of multiplication rather than a time given. This factor now multiplies the maximum script execution time as determined by your server's PHP settings. I also worked it into a class definition.
PHP Syntax (Toggle Plain Text)
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis Last edited by grimpirate; Jan 15th, 2008 at 1:56 PM. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| problem processing file into a char array | csrocker101 | C++ | 1 | May 8th, 2007 11:50 PM |
| add mutiple users to the smbpasswd file. | Pizentios | Bash / Shell Scripting | 3 | Oct 20th, 2005 12:48 PM |
| After execution - Error cannot locate /Skin File? | wchar | Visual Basic | 1 | Mar 5th, 2005 9:04 PM |
| airport Log program using 3D linked List : problem reading from file | gemini_shooter | C++ | 0 | Mar 2nd, 2005 4:12 PM |
| Structure char field to a disk file | ehab_aziz2001 | C++ | 0 | Feb 10th, 2005 2:42 PM |