PHP program in the file lock, mutex, read and write the use of skills analysis,
File lock
Full name advisory file lock, which is mentioned in the book. This type of lock is more common, such as MySQL, after php-fpm boot, there will be a PID file record the process ID, this file is a file lock.
This lock prevents a process from running repeatedly, such as qualifying every minute of a task when using crontab, but the process can run for more than a minute, and if a process lock is not used to resolve the conflict, there will be a problem with two processes executing together.
Using a PID file lock also has the advantage of allowing the process to stop or restart the signal itself. For example, the command to restart PHP-FPM is
KILL-USR2 ' Cat/usr/local/php/var/run/php-fpm.pid '
The process of sending the USR2 signal to the PID file record, the signal belongs to the process communication, will open another space.
PHP interface is flock, the document is more detailed. First look at the definition, bool flock (resource $handle, int $operation [, int & $wouldblock]).
- The $handle is a file system pointer, which is a resource (resource) typically created by fopen (). This means that you must open a file using flock.
- $operation is the type of operation.
- & $wouldblock If the lock is blocked, the variable is set to 1.
It is important to note that this function is blocked by default, and if you want non-blocking you can add a bitmask lock_nb to the operation. Next Test.
$pid _file = "/tmp/process.pid"; $pid = Posix_getpid (); $fp = fopen ($pid _file, ' w+ '); if (Flock ($fp, LOCK_EX | LOCK_NB) { echo "got the lock \ n"; Ftruncate ($fp, 0); Truncate file fwrite ($fp, $pid); Fflush ($FP); Flush output before releasing the lock Sleep,//long running Process flock ($fp, lock_un); Release Lock} else { echo "cannot get PID lock. The process is already up \ n ";} Fclose ($FP);
Save As process.php, run PHP process.php &, and then run PHP process.php again to see the error message. Flock also has a shared lock, lock_sh.
mutexes and read-write locks
The mutex in the Sync module:
A mutex is a combination of words, mutual exclusion. Install the Sync module with PECL and pecl installed sync. The Syncmutex in the document is only two methods, lock and unlock, and we'll go straight to the code test. Do not write with the IDE, so the CS is unusually ugly, please ignore.
$mutex = new Syncmutex ("UniqueName"); for ($i =0; $i <2; $i + +) { $pid = Pcntl_fork (); if ($pid <0) {die ("fork Failed"); } ElseIf ($pid >0) { echo "parent process \ n"; } else{ echo "child process {$i} is born. \ n "; Obtainlock ($mutex, $i);} } while (pcntl_waitpid (0, $status)! =-1) { $status = Pcntl_wexitstatus ($status); echo "Child $status completed\n"; }function Obtainlock ($mutex, $i) { echo "process {$i} is getting the mutex \ n"; $res = $mutex->lock (+); Sleep (1); if (! $res) { echo "process {$i} Unable to lock mutex. \ n "; } else{ echo "process {$i} successfully got the mutex \ n"; $mutex->unlock (); } Exit ();}
Save As mutex.php, run PHP mutex.php, output is
Parent process Parent Process Child Process 1 is born. Process 1 is getting the mutex child process 0 is born. Process 0 is getting the mutex process 1 successfully got the mutex child 0 completedprocess 0 Unable to lock mutex. Child 0 completed
Here child processes 0 and 1 are not necessarily who are in front. But there's always one that can't be locked. Here the Syncmutex::lock (int $millisecond) parameter is millisecond, which represents the length of the block, and 1 is an infinite block.
Read and write locks in the Sync module:
Syncreaderwriter method Similar, Readlock, Readunlock, Writelock, Writeunlock, in pairs appear can, did not write the test code, should and the mutex code consistent, the lock can be replaced.
event in the Sync module:
It feels like the cond in Golang, wait () blocks, and fire () wakes up the event blocking a process. There is a good article introduced cond, you can see that cond is a fixed use of locks. The same is true of syncevent.
The example in the PHP documentation shows that the fire () method seems to work in a Web application.
On the test code
for ($i =0; $i <3; $i + +) { $pid = Pcntl_fork (); if ($pid <0) {die ("fork Failed"); } ElseIf ($pid >0) { //echo "parent process \ n"; } else{ echo "child process {$i} is born. \ n "; Switch ($i) {case 0: wait (); break; Case 1: wait (); break; Case 2: sleep (1); Fire (); Break;}}} while (pcntl_waitpid (0, $status)! =-1) { $status = Pcntl_wexitstatus ($status); echo "Child $status completed\n"; }function Wait () { $event = new Syncevent ("UniqueName"); echo "before waiting. \ n "; $event->wait (); echo "After waiting. \ n "; Exit ();} function Fire () { $event = new Syncevent ("UniqueName"); $event->fire (); Exit ();}
There is a deliberate lack of writing a fire (), so the program blocks and proves that fire () wakes up only one process at a time.
Pthreads Module
Locking and unlocking mutexes:
Function:
Usage:
The thread uses the Pthread_mutex_lock () function to lock the specified mutex variable, and if the mutex is already locked by another thread, the call will block the thread until the mutex is unlocked.
Pthread_mutex_trylock () would attempt to lock a mutex. However, if the mutex is already locked, the routine would return immediately with a "busy" error code. This routine is useful in pthread_mutex_trylock ().
Try to lock a mutex, however, if the mutex is locked, the program returns immediately and returns a busy error value. This function is useful for blocking deadlocks in the event of a priority change. Threads can use Pthread_mutex_unlock () to unlock the amount of mutex they occupy. This function can be called when one thread completes the use of the protected data, while other threads are getting mutexes to work on the protected data. If there is a situation, an error will occur:
- Mutex has been unlocked
- Mutex is occupied by another thread
Mutexes are not so "magical", in fact, they are the "gentlemen's bargain" of participating threads. When writing code, be sure to lock correctly and unlock the mutex.
Q: There are multiple threads waiting for the same locked mutex, and when the mutex is unlocked, that thread will first lock the mutex?
A: Unless the thread uses a priority scheduling mechanism, the thread will be allocated by the system scheduler, and that thread will be the first to lock the mutex is random.
#include
#include
#include
#include
typedef struct CT_SUM {int sum; pthread_mutex_t lock; }ct_sum; void * ADD1 (void *cnt) {Pthread_mutex_lock (& ((ct_sum*) CNT)->lock); for (int i=0; i <; i++) {(* (ct_sum*) CNT). sum + = i; } Pthread_mutex_unlock (& ((ct_sum*) CNT)->lock); Pthread_exit (NULL); return 0; } void * ADD2 (void *cnt) {Pthread_mutex_lock (& ((ct_sum*) CNT)->lock); for (int i=50; i<101; i++) {(* (ct_sum*) CNT). sum + = i; } Pthread_mutex_unlock (& ((ct_sum*) CNT)->lock); Pthread_exit (NULL); return 0; } int main (void) {pthread_t ptid1, Ptid2; Ct_sum CNT; Pthread_mutex_init (& (Cnt.lock), NULL); cnt.sum=0; Pthread_create (&ptid1, NULL, Add1, &cnt); Pthread_create (&ptid2, NULL, ADD2, &cnt); Pthread_join (Ptid1,null); Pthread_join (Ptid2,null); printf ("Sum%d\n", cnt.sum); Pthread_mutex_destroy (& (Cnt.lock)); return 0; }
Signal Volume
Signal volume in the Sync module:
The Syncsemaphore document shows that it differs from a mutex in that semaphore can be obtained by multiple processes (or threads) at a time, and the mutex can only be obtained by one at a time. So in Syncsemaphore's constructor, there is a parameter that specifies how many processes the semaphore can get.
Public Syncsemaphore::__construct ([string $name [, Integer $initialval [, BOOL $autounlock]]) is this $initialval (Initia L value)
$lock = new Syncsemaphore ("UniqueName", 2); for ($i =0; $i <2; $i + +) { $pid = Pcntl_fork (); if ($pid <0) {die ("fork Failed"); } ElseIf ($pid >0) { echo "parent process \ n"; } else{ echo "child process {$i} is born. \ n "; Obtainlock ($lock, $i);} } while (pcntl_waitpid (0, $status)! =-1) { $status = Pcntl_wexitstatus ($status); echo "Child $status completed\n"; }function Obtainlock ($lock, $i) { echo "process {$i} is getting the lock \ n"; $res = $lock->lock (+); Sleep (1); if (! $res) { echo "process {$i} Unable to lock lock. \ n "; } else{ echo "process {$i} successfully got the lock \ n"; $lock->unlock (); } Exit ();}
At this time two processes can be locked.
- Semaphores in the Sysvsem module
- Sem_get Creating semaphores
- Sem_remove Delete semaphore (not normally used)
- Sem_acquire request to get the semaphore
- Sem_release The amount of signal released. And Sem_acquire are used in pairs.
$key = Ftok ('/tmp ', ' C '); $sem = Sem_get ($key); for ($i =0; $i <2; $i + +) { $pid = Pcntl_fork (); if ($pid <0) {die ("fork Failed"); } ElseIf ($pid >0) { //echo "parent process \ n"; } else{ echo "child process {$i} is born. \ n "; Obtainlock ($sem, $i);} } while (pcntl_waitpid (0, $status)! =-1) { $status = Pcntl_wexitstatus ($status); echo "Child $status completed\n"; }sem_remove ($sem); Finally remove the Semfunction obtainlock ($sem, $i) { echo "process {$i} is getting the SEM \ n"; $res = Sem_acquire ($sem, true); Sleep (1); if (! $res) { echo "process {$i} unable to get SEM. \ n"; } else{ echo "process {$i} successfully got the SEM \ n"; Sem_release ($sem); } Exit ();}
Here's a question, Sem_acquire () the second parameter, $nowait, defaults to false, blocking. I set to true, if the lock fails, then the Sem_release will report the warning PHP warning:sem_release (): SysV semaphore 4 (key 0x63000081) is not currently Acqui Red in/home/jason/sysvsem.php on line 33, so here the release operation must be placed in the case of a lock to execute, the previous few examples do not have this problem, do not get lock execution release will not error. Of course, it is best to appear in pairs and make sure that you get the lock and release again.
In addition, ftok the parameter of this method is necessary to explain, the first must be existing, accessable file, generally use the file in the project, the second is a single character string. Returns an int.
Output to
Parent process Parent Process Child Process 1 is born. Process 1 is getting the mutex child process 0 is born. Process 0 is getting the mutex process 1 successfully got the mutex child 0 completedprocess 0 Unable to lock mutex. Child 0 completed
Articles you may be interested in:
- The lock and concurrency of the PHP session
- PHP uses flock to implement file lock method
- Workaround for blocking problems caused by exclusive lock of PHP session file
- Use Memache as a process lock in PHP to share the Operation class
- PHP to lock and unlock the file instance
- PHP file Lock function Flock () detailed description
- PHP implements multi-machine interlock instances by inserting MySQL data
- PHP file Lock Write instance parsing
- How to resolve session deadlock with PHP
- PHP Flock File Lock detailed description
- PHP specific implementation code for common locking and locks under concurrency
- Phplock (PHP process Lock) v1.0 BETA1
- Analysis and research of PHP process lock problem
- Get increment sequence ID by system semaphore Lock method under PHP
http://www.bkjia.com/PHPjc/1113732.html www.bkjia.com true http://www.bkjia.com/PHPjc/1113732.html techarticle PHP program file lock, mutual exclusion lock, read and write lock use skill parsing, file lock full name is advisory file lock, the book is mentioned. This type of lock is more common, such as MySQL, php-fpm startup ...