Solution for concurrent Read and write file conflicts in PHP (file lock application example)

Source: Internet
Author: User
Tags flock

PHP (foreign name: Hypertext Preprocessor, Chinese name: "Hypertext Preprocessor") is a common open source scripting language. Grammar absorbs the C language, Java and Perl features, the entry threshold is low, easy to learn, widely used, mainly for the field of web development. PHP has a file suffix called PHP.

This article is for you to explain the concurrency of the PHP file conflict resolution (file lock application example), interested students reference.

Here provides 4 kinds of high concurrency read and write files, each has the advantage, can according to their own situation to solve the problem of PHP concurrent read and write file conflicts.

For the day IP is not high or the number of concurrent is not a very large application, generally do not consider these! There is absolutely no problem with the normal file operation method. However, if the concurrency is high, when we read and write to the file, it is very likely that more than one process in a file to operate, if not the corresponding exclusive access to the file, it is easy to cause data loss.
For example: an online chat room (which assumes that the chat content is written to a file), at the same time, both user A and User B have to manipulate the data to save the file, the first is a open the file, and then update the data inside, but here B also opened the same file, also ready to update the data inside. When a writes a well-written file, it actually opens the file. But when B again save the file back, this has caused the loss of data, because here B users completely do not know that the file it opened when it changes it, a user also changed the file, so the last B user save changes, User A's update will be lost.
For such a problem, the general solution when a process on the file operation, the first to lock the other, meaning that only the process has the right to read the file, the other process if read now, is completely no problem, but if there is a process trying to update it, will be rejected by the operation, The previous process of locking the file then releases the exclusive identity if the update to the file is complete, and the file reverts to the state that can be changed. In the same vein, if the process in the operation of the file, the file is not locked, then it can be assured that the bold file lock, enjoy alone.
The general scenario would be:


$fp =fopen ('/tmp/lock.txt ', ' w+ ');
if (Flock ($FP, lock_ex)) {
Fwrite ($fp, "Write something Heren");
Flock ($FP, lock_un);
}else{
echo ' couldn ' t lock the file! ';
}
Fclose ($FP);


But in PHP, Flock seems to be not working so well! In the case of multiple concurrency, it seems that the resources are often exclusive, not released immediately, or not released at all, resulting in a deadlock, which makes the server CPU occupied very high, and sometimes the server is completely dead. It seems that in many Linux/unix systems, this happens. So before using flock, be sure to consider carefully.
So there's no solution? In fact, it is not the case. If Flock () is used properly, it is possible to solve the deadlock problem. Of course, if you do not consider the use of the flock () function, there will also be a good solution to solve our problem. After my personal collection and summary, roughly summed up the solution has the following several.
Scenario One: When the file is locked, set a time-out. the approximate implementation is as follows:


if ($fp =fopen ($fileName, ' a ')) {
$startTime =microtime ();
do{
$canWrite =flock ($fp, LOCK_EX);
if (! $canWrite) {
Usleep (Round (rand (0,100) *1000));
}
}while ((! $canWrite) && ((Microtime ()-$startTime) <1000));
if ($canWrite) {
Fwrite ($fp, $dataToSave);
}
Fclose ($FP);
}


Timeout set to 1ms, if there is no lock in time, it is repeatedly obtained, directly to the file operation right, of course. If the time-out limit is reached, it is necessary to exit immediately and let the other process do the lock.

Scenario Two: Do not use the flock function, borrowing temporary files to solve the problem of read-write conflicts. The general principle is as follows:
(1) Consider a copy of the files that need to be updated to our temp file directory, save the file last modified time to a variable, and take a random, not easy duplicate file name for this temporary file.
(2) When the temporary file is updated, the last update time of the original file is checked and the time saved is the same as before.
(3) If the last modification time is consistent, the modified temporary file is renamed to the original file, in order to ensure the file status synchronization update, so you need to clear the file status.
(4) However, if the last modification time is consistent with the previous save, this indicates that during this period the original file has been modified, then the temporary file needs to be deleted, and then return false, stating that there are other processes in the file at this time.
The implementation code is as follows:


$dir _fileopen= ' tmp ';
function Randomid () {
return time (). substr (MD5 (Microtime ()), 0,rand (5,12));
}
function Cfopen ($filename, $mode) {
Global $dir _fileopen;
Clearstatcache ();
do{
$id =md5 (Randomid (rand (), TRUE));
$tempfilename = $dir _fileopen. ' /'. $id. MD5 ($FILENAME);
} while (File_exists ($tempfilename));
if (file_exists ($filename)) {
$newfile =false;
Copy ($filename, $tempfilename);
}else{
$newfile =true;
}
$FP =fopen ($tempfilename, $mode);
return $fp? Array ($fp, $filename, $id, @filemtime ($filename)): false;
}
function Cfwrite ($fp, $string) {
return fwrite ($fp [0], $string);
}
function Cfclose ($fp, $debug = ' off ') {
Global $dir _fileopen;
$success =fclose ($fp [0]);
Clearstatcache ();
$tempfilename = $dir _fileopen. ' /'. $fp [2].md5 ($fp [1]);
if (@filemtime ($fp [1]) = = = $FP [3]) | | ($fp [4]==true&&!file_exists ($fp [1]) | | $fp [5]==true) {
Rename ($tempfilename, $fp [1]);
}else{
Unlink ($tempfilename);
Indicates that there are other processes in the operation target file, the current process is rejected
$success =false;
}
return $success;
}
$fp =cfopen (' lock.txt ', ' A + ');
Cfwrite ($FP, "Welcome to BEIJING.N");
Fclose ($fp, ' on ');


For the functions used in the above code, you need to explain:
(1) rename (); Rename a file or a directory, which is actually more like a MV in Linux. It is convenient to update the path or name of the file or directory. But when I test the above code in window, if the new file name already exists, it gives a notice that the current file already exists. But it works well under Linux.
(2) Clearstatcache (); Clears the status of the file. PHP caches all file attribute information to provide higher performance, but sometimes when a multi-process deletes or updates a file, PHP does not have time to update the file attributes in the cache, which can lead to access to the last update date that is not real data. So you need to use this function to clear the saved cache.

Scenario Three: The operation of the file random read and write to reduce the likelihood of concurrency.
This scenario seems to be more widely used when logging user access logs. Before the need to define a random space, the larger the space, the more likely the likelihood of concurrency, where random read and write space is assumed to be [1-500], then our log file distribution is log1~ to log500 range. Each time a user accesses, the data is randomly written to any file between log1~log500. At the same time, there are 2 processes logging, the A process may be the updated LOG32 file, and the B process? The update may be log399 at this point. You know, if you want the B process to operate the LOG32, the probability is basically 1/500, almost equal to zero. When the access log needs to be analyzed, we just need to merge the logs before analyzing them. When you use this scenario to record one benefit of logging, process operations are less likely to be queued, allowing the process to complete each operation very quickly.

Scenario Four: Put all the processes you want to manipulate into one queue. then dedicate a service to complete the file operation. Each of the excluded processes in the queue is equivalent to the first specific operation, so the first time our service only needs to get the equivalent of the actual operation from the queue, if there are a lot of file operation process, it's OK, to queue up behind us, as long as willing to platoon, queue of how long it doesn't matter.

For the previous several programs, each has its own benefits! Broadly, it may be summed up into two categories:
(1) Need to queue (slow impact) such as plan one, two or four
(2) no queuing required. (Impact fast) Programme III
When designing a caching system, we typically do not use scenario three. Because the analysis program of scenario three and the writer is not synchronized, at the time of writing, completely regardless of the time to analyze the difficulty, just write the line. Imagine that when we update a cache, if we also take random file reading, it seems to be a lot more process to read the cache. However, the adoption of scenario one or two is completely different, although the write time needs to wait (when the acquisition lock is not successful, will be repeatedly acquired), but read the file is very convenient. The purpose of adding a cache is to reduce the data read bottleneck, which improves system performance.
From the summary of personal experience and some information, there is something wrong, or not mentioned in the place, you are welcome to correct your colleague.

Solution for concurrent Read and write file conflicts in PHP (file lock application example)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.