In the case of high concurrency, the operation of the same file can result in data confusion, so you need to do some special processing when working with files, and here are a few solutions to summarize. Hope to help everyone.
Scenario One: Use the Flock function to lock the file
/*
* Flock (File,lock,block)
* File required to lock or release open files
* Lock required. Specifies which type of lock to use.
* block is optional. If set to 1 or true, the other process is blocked when the lock is made.
* Lock
* Lock_sh to get a shared lock (read program)
* LOCK_EX to acquire an exclusive lock (written program)
* Lock_un to release the lock (whether shared or exclusive)
* LOCK_NB If you do not want flock () to block when locked
/*
Get lock if (flock ($file, lock_ex)) { //action file
Fwrite ($file, ' write more words ');
Release the lock when the operation is complete
Flock ($file, lock_un);
} else {
Handling Error Logic
}
Fclose ($file);
The Flock function, in the case of multiple concurrency, seems to often monopolize resources, do not release them immediately, or do not release them at all, causing deadlocks, which can make the server CPU high and sometimes even kill the server completely. So simply using flock lock does not solve the problem completely.
Scenario Two: Limit the lock time, timeout to exit
if ($fp = fopen ($fileName, ' a ')) { $startTime = Microtime (); do{ $canWrite = Flock ($fp, lock_ex); if (! $canWrite) {
Usleep (Round (rand (0) *)); Frees the CPU and gives the CPU resources to other processes first
} //If the lock is not acquired and does not time out, continue acquiring the lock
} while ((! $canWrite) && ((Microtime ()-$startTime) <)); if ($canWrite) { fwrite ($fp, $dataToSave);
Flock ($file, lock_un);
} fclose ($FP);
}
Scenario three: Using temporary files
$dir _fileopen= ' tmp '; function Cfopen ($filename, $mode) {
Global $dir _fileopen;
Clearstatcache (); Create a temporary file
do{$id =uniqid (); $tempfilename = $dir _fileopen. ' /'. $id. MD5 ($FILENAME);
} while (File_exists ($tempfilename)); Copy the contents of the file you want to manipulate into a temporary file
Copy ($filename, $tempfilename); $fp = fopen ($tempfilename, $mode); Return $fp? [$fp, $filename, $id, @filemtime ($filename)]: false;
}function Cfwrite ($fp, $string) {
Write new content to a temporary file
return fwrite ($fp [0], $string);
}function Cfclose ($fp) {
Global $dir _fileopen; $success = fclose ($fp [0]);
Clearstatcache (); $tempfilename = $dir _fileopen. ' /'. $fp [2].md5 ($fp [1]); If the file you want to manipulate has not been modified during the operation, it means that no one has manipulated the file, so rename the temporary file to a real file
if (@filemtime ($fp [1]) = = = $FP [3]) {
Rename ($tempfilename, $fp [1]);
}else{//Indicates that there are other processes in the operation target file, the current process is rejected, the temporary files are deleted
Unlink ($tempfilename); $success = false;
} return $success;
} $startTime = Microtime ();d o{$fp =cfopen (' lock.txt ', ' A + ');
Cfwrite ($FP, "Welcome to beijing.\n"); $success = Cfclose ($fp, ' on '); if (! $success) {
Usleep (Round (rand (0, 100) * 1000)); Frees the CPU and gives the CPU resources to other processes first
}
}while (! $success && ((Microtime ()-$startTime) < 1000)); If False, indicates that the operation failed, then the operation is restarted
Scenario Four: Using queues
Create a queue of file operations, and then write a script from the queue to read the file operation of the information and then the corresponding operation of the file, so that each time only one process in the operation of the file, it solves the problem of concurrency.
The above information is from: http://blog.csdn.net/daiyan_csdn/article/details/51524781
In the case of high concurrency, the operation of the same file can result in data confusion, so you need to do some special processing when working with files, and here are a few solutions to summarize.
Scenario One: Use the Flock function to lock the file
/*
* Flock (File,lock,block)
* File required to lock or release open files
* Lock required. Specifies which type of lock to use.
* block is optional. If set to 1 or true, the other process is blocked when the lock is made.
* Lock
* Lock_sh to get a shared lock (read program)
* LOCK_EX to acquire an exclusive lock (written program)
* Lock_un to release the lock (whether shared or exclusive)
* LOCK_NB If you do not want flock () to block when locked
/*
Get lock if (flock ($file, lock_ex)) { //action file
Fwrite ($file, ' write more words ');
Release the lock when the operation is complete
Flock ($file, lock_un);
} else {
Handling Error Logic
}
Fclose ($file);
The Flock function, in the case of multiple concurrency, seems to often monopolize resources, do not release them immediately, or do not release them at all, causing deadlocks, which can make the server CPU high and sometimes even kill the server completely. So simply using flock lock does not solve the problem completely.
Scenario Two: Limit the lock time, timeout to exit
if ($fp = fopen ($fileName, ' a ')) { $startTime = Microtime (); do{ $canWrite = Flock ($fp, lock_ex); if (! $canWrite) {
Usleep (Round (rand (0) *)); Frees the CPU and gives the CPU resources to other processes first
} //If the lock is not acquired and does not time out, continue acquiring the lock
} while ((! $canWrite) && ((Microtime ()-$startTime) <)); if ($canWrite) { fwrite ($fp, $dataToSave);
Flock ($file, lock_un);
} fclose ($FP);
}
Scenario three: Using temporary files
$dir _fileopen= ' tmp '; function Cfopen ($filename, $mode) {
Global $dir _fileopen;
Clearstatcache (); Create a temporary file
do{$id =uniqid (); $tempfilename = $dir _fileopen. ' /'. $id. MD5 ($FILENAME);
} while (File_exists ($tempfilename)); Copy the contents of the file you want to manipulate into a temporary file
Copy ($filename, $tempfilename); $fp = fopen ($tempfilename, $mode); Return $fp? [$fp, $filename, $id, @filemtime ($filename)]: false;
}function Cfwrite ($fp, $string) {
Write new content to a temporary file
return fwrite ($fp [0], $string);
}function Cfclose ($fp) {
Global $dir _fileopen; $success = fclose ($fp [0]);
Clearstatcache (); $tempfilename = $dir _fileopen. ' /'. $fp [2].md5 ($fp [1]); If the file you want to manipulate has not been modified during the operation, it means that no one has manipulated the file, so rename the temporary file to a real file
if (@filemtime ($fp [1]) = = = $FP [3]) {
Rename ($tempfilename, $fp [1]);
}else{//Indicates that there are other processes in the operation target file, the current process is rejected, the temporary files are deleted
Unlink ($tempfilename); $success = false;
} return $success;
} $startTime = Microtime ();d o{$fp =cfopen (' lock.txt ', ' A + ');
Cfwrite ($FP, "Welcome to beijing.\n"); $success = Cfclose ($fp, ' on '); if (! $success) {
Usleep (Round (rand (0, 100) * 1000)); Frees the CPU and gives the CPU resources to other processes first
}
}while (! $success && ((Microtime ()-$startTime) < 1000)); If False, indicates that the operation failed, then the operation is restarted
Scenario Four: Using queues
Create a queue of file operations, and then write a script from the queue to read the file operation of the information and then the corresponding operation of the file, so that each time only one process in the operation of the file, it solves the problem of concurrency.