Bool flock (int handle, int operation [, int & wouldblock]);
The handle of the flock () operation must be an opened file pointer. Operation can be one of the following values:
1. To obtain the shared Lock (read program), set operation to LOCK_SH (PHP 4.0.1 and earlier versions to 1)
2. To obtain an exclusive lock (write program), set operation to LOCK_EX (set to 2 in versions earlier than PHP 4.0.1)
3. To release the lock (whether shared or exclusive), set operation to LOCK_UN (set it to 3 in versions earlier than PHP 4.0.1)
4. If you do not want flock () to be blocked during locking, add LOCK_NB to operation (set it to 4 in PHP versions earlier than 4.0.1)
Create two files
The code is as follows: |
Copy code |
(1) a. php ? $ File = "temp.txt "; $ Fp = fopen ($ file, 'w '); If (flock ($ fp, LOCK_EX )){ Fwrite ($ fp, "abcn "); Sleep (10 ); Fwrite ($ fp, "123n "); Flock ($ fp, LOCK_UN ); } Fclose ($ fp ); (2) B. php ? $ File = "temp.txt "; $ Fp = fopen ($ file, 'r '); Echo fread ($ fp, 100 ); Fclose ($ fp ); |
After running a. php, run B. php immediately. The output is displayed:
Abc
After a. php is run, run B. php. The output is as follows:
Abc
123
Apparently, when a. php writes a file with a large amount of data, resulting in a long time, B. php reads incomplete data.
Modify B. php:
The code is as follows: |
Copy code |
? $ File = "temp.txt "; $ Fp = fopen ($ file, 'r '); If (flock ($ fp, LOCK_EX )){ Echo fread ($ fp, 100 ); Flock ($ fp, LOCK_UN ); } Else { Echo "Lock file failed... n "; } Fclose ($ fp );
|
After running a. php, run B. php immediately. You can find that B. php will not be displayed until a. php is completed (10 seconds later:
Abc
123
The read data is complete, but it takes too long to wait for the write lock to be released.
Modify B. php:
The code is as follows: |
Copy code |
? $ File = "temp.txt "; $ Fp = fopen ($ file, 'r '); If (flock ($ fp, LOCK_SH | LOCK_NB )){ Echo fread ($ fp, 100 ); Flock ($ fp, LOCK_UN ); } Else { Echo "Lock file failed... n "; } Fclose ($ fp );
|
After running a. php, run B. php immediately. The output is displayed:
Lock file failed...
It proves that the lock file failure status can be returned, rather than waiting for a long time as it goes up.
Conclusion:
We recommend that you select related locks when caching files. Otherwise, the read data may be incomplete or the data may be written repeatedly.
File_get_contents does not seem to be able to select a lock and does not know what locks it uses by default. The reverse is the same as the output obtained by the unlock, which is incomplete data.
I want to cache files, so I only need to know whether a write lock exists. If yes, I can check the database.
Although 100 rows are written at the same time, the data in transaction 1 and transaction 2 is staggered, which is not the expected result. What we need is the complete execution of the transaction. At this time, we need a mechanism to ensure that the second transaction is executed after the first transaction is executed. In PHP, flock functions fulfill this mission. Add flock ($ fp, LOCK_EX) before the loop of transaction 1 and transaction 2 to meet our needs and serialize two transactions.
When a transaction finishes flock execution, because LOCK_EX (exclusive lock) is added here, all operations on the resource will be blocked, only after the transaction is completed, the subsequent transactions will be executed. We can confirm this by outputting the current time.
For append write at the end, a concurrent write problem exists in earlier versions of the unix system. To append at the end, you must first append at the lseek position before writing. When multiple processes operate at the same time, the write overwrite issue will be caused by Concurrency. That is, after both processes get the tail offset at the same time, the write operation will be executed successively, the subsequent operations will overwrite the previous operations. This problem is solved by adding the O_APPEND operation when opening. It turns the search and write operations into an atomic operation.
In the implementation of the fopen function in PHP, if we use the parameter to append content to the end of the file, the oflag parameter in the call to the open function is O_CREAT | O_APPEND, that is, we do not need to worry about concurrent append writing when using the append operation.
The flock file lock is also used in the default session storage implementation of PHP. When the session starts, PS_READ_FUNC is called, and the session data file is opened with O_CREAT | O_RDWR | O_BINARY. The flock and write locks are called at this time, if another process accesses this file (that is, the same user initiates a request to the current file again), the page is loaded and the process is blocked. The starting point of the write lock is to ensure the complete execution of session operation transactions in this session, prevent interference from other processes, and ensure data consistency. If a page does not have a session modification operation, you can call session_write_close () to release the lock as soon as possible.
A file lock is a file lock. In addition to this definition, it can also be understood as a file lock. In actual work, sometimes to ensure the execution of a single process, we will determine whether the file exists before the execution of the program. If it does not exist, create an empty file, delete the empty file after the process ends. If it exists, it is not executed.
But when will lock_ex be used?
When reading:
If you do not want dirty data to appear, it is best to use the lock_sh shared lock. You can consider the following three situations:
1. If the shared lock is not applied during read, other programs will write the lock immediately (no matter whether the write is locked or not. If half of the data is read and written by other programs, the last half of the data read may be less than the first half (the first half is before the modification, the last half is modified)
2. if a shared lock is added during read (because it is only read, there is no need to use the exclusive lock), at this time, other programs start to write, this write program does not use the lock, then, writing a program will directly modify this file, which will lead to the same problem as above.
3. the ideal situation is that lock_sh is used during read and lock_ex is used during write. In this way, the write program will wait until the Read program is complete, there will be no hasty operations
When writing:
If multiple write programs operate on files without locking, some of the final data may be written by program a and some by program B.
If the lock is applied during the write process and other programs are used to read the lock, what will the program read?
1. If the Read program does not apply for a shared lock, it will read the data of dirty. For example, to write a program, write a, B, and c, and write a. At this time, read a and continue to write B. At this time, read AB and then write c, at this time, I read abc.
2. If the Read program has applied for a shared lock before, the Read program will read it only after the write program finishes writing abc and releases the lock.