1. Distinguish between read lock and write lock.
If a write lock is used every time, it is not efficient to even read a single file into a queue for multiple processes.
2. Differentiate between blocking and non-blocking modes.
In general, if a process is writing a file, another process should be blocked, but, many times, we can do something else first,
Then decide if there are other people writing files, if not, then add data, this is more efficient.
3. Fixed a bug that locked files on Linux, especially on GFS file system.
The code is as follows:
Copy CodeThe code is as follows:
Class File_lock
{
Private $name;
Private $handle;
Private $mode;
function __construct ($filename, $mode = ' a+b ')
{
Global $php _errormsg;
$this->name = $filename;
$path = dirname ($this->name);
if ($path = = '. ' | |!is_dir ($path)) {
Global $config _file_lock_path;
$this->name = str_replace (Array ("/", "\ \"), Array ("_", "_"), $this->name);
if ($config _file_lock_path = = null) {
$this->name = dirname (__file__). "/lock/". $this->name;
} else {
$this->name = $config _file_lock_path. "/" . $this->name;
}
}
$this->mode = $mode;
$this->handle = @fopen ($this->name, $mode);
if ($this->handle = = False) {
throw new Exception ($php _errormsg);
}
}
Public Function Close ()
{
if ($this->handle!== null) {
@fclose ($this->handle);
$this->handle = null;
}
}
Public Function __destruct ()
{
$this->close ();
}
Public function Lock ($lockType, $nonBlockingLock = False)
{
if ($nonBlockingLock) {
Return Flock ($this->handle, $lockType | LOCK_NB);
} else {
Return Flock ($this->handle, $lockType);
}
}
Public Function Readlock ()
{
return $this->lock (LOCK_SH);
}
Public Function Writelock ($wait = 0.1)
{
$startTime = Microtime (true);
$canWrite = false;
do {
$canWrite = Flock ($this->handle, LOCK_EX);
if (! $canWrite) {
Usleep (rand (10, 1000));
}
} while ((! $canWrite) && ((Microtime (True)-$startTime) < $wait));
}
/**
* If you want ' t to log the number under Multi-thread system,
* Please open the lock and use a + mod. Then fopen the file would not
* Destroy the data.
*
* This function increment a delt value, and save to the file.
*
* @param int $delt
* @return int
*/
Public Function Increment ($delt = 1)
{
$n = $this->get ();
$n + = $delt;
$this->set ($n);
return $n;
}
Public function Get ()
{
Fseek ($this->handle, 0);
return (int) fgets ($this->handle);
}
Public function set ($value)
{
Ftruncate ($this->handle, 0);
Return fwrite ($this->handle, (string) $value);
}
Public function unlock ()
{
if ($this->handle!== null) {
Return Flock ($this->handle, Lock_un);
} else {
return true;
}
}
}
?>
Test code:
Copy CodeThe code is as follows:
/**
* Test for Write lock
* Open Thread 1
*/
Require ("file_lock.php");
$lock = new File_lock (dirname (dirname (__file__)). "/filelock.lock");
/** A single thread locks the speed of 1s clock 30,000 times. **/
/** Two threads write, 20,000 of the data is about 7s clock */
/** a thread write, 10,000 of the data about 3.9s clock, incredibly two files at the same time to write, be quick * *
/** does not lock, a process write about 2.8s clock, locking is a price. */
/** does not lock, two processes are not evenly distributed, and most of them are in conflict */
$lock->writelock ();
$lock->increment ();
$lock->unlock ();
while ($lock->get () < 2) {
Usleep (1000);
}
Sleep (1);
echo "begin to runing \ n";
$t 1 = microtime (true);
for ($i = 0; $i < 10000; $i + +)
{
$lock->writelock ();
$lock->increment (1);
$lock->unlock ();
}
$t 2 = Microtime (True)-$t 1;
echo $t 2;
?>
I added a increment function that enables simple thread synchronization, allowing two processes to execute a piece of code at the same time, which, of course, has some error
The error here is 0.001s.
A thread-safe message queue can be implemented simply by using this class in the previous Memcache message queue.
http://www.bkjia.com/PHPjc/320820.html www.bkjia.com true http://www.bkjia.com/PHPjc/320820.html techarticle 1. Distinguish between read lock and write lock. If a write lock is used every time, it is not efficient to even read a single file into a queue for multiple processes. 2. Distinguish between blocking and non-...