Sorry for my English.
First, I will talk about some common features:
First, let's make the file implementation. We will use the built-in flock function (thanks to Salman A ).
<?php $fname = 'test.txt'; $file = fopen($fname, 'a+'); sleep(5); // long operation if(flock($file,LOCK_EX|LOCK_NB )){// we get file lock - $semaphore->lock(); sleep(5); // long operation fputs($file, "\n".date('dmY H:i:s')); //something dangerous echo 'writed'; flock($file,LOCK_UN ); // release lock - $semaphore->unlock(); }else{ // file already locked echo 'LOCKED'; } fclose($file);
Secondly, do a database lock. In general, some databases may have a write lock mechanism on a single table, in which case you should use this mechanism. But other databases did not support this feature, for example MySql. In this case, let's do the magic :)
For example, we have a simple table
CREATE TABLE `threading` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `val` INT(10) NOT NULL, PRIMARY KEY (`id`) )COLLATE='utf8_general_ci' ENGINE=InnoDB
Allows you to add a column that will simulate a "lock" entry:
ALTER TABLE `threading` ADD COLUMN `_lock` BIT NOT NULL AFTER `val`;
Now we can set _lock fild to 1 for a locked write!
IMPORTANT : you must make the lock one request as follows: update threading set _lock = 1 where id = 1 AND _lock <> 1 ; .
Note: AND _lock <> 1 prevent the record from being locked when it is already locked, so you can decide whether the record was locked by the rows_affected mechanism.
<?php // connect mysql_connect('localhost','root','root'); mysql_selectdb('testing'); // get info $res = mysql_query('select * from threading where id = 1;'); $row = mysql_fetch_assoc($res); print_r($row); // debug if($row['val']>=70){ sleep(5); // emulate long-long operation =) // try to lock mysql_query('update threading set _lock = 1 where id = 1 AND _lock <> 1 ;'); // _lock <> 1 - very IMPORTANT! sleep(5); // emulate long-long operation =) $affected_rows = mysql_affected_rows(); if($affected_rows!=1){ // lock failed - locked by another instance echo '<br> LOCKED!'; }else{ // lock succeed mysql_query('update threading set val = val-70 where id = 1;');//something dangerous mysql_query('update threading set _lock = 0 where id = 1;'); // UNLOCK! } } // view result $res = mysql_query('select * from threading where id = 1;'); $row2 = mysql_fetch_assoc($res); echo '<br>'; print_r($row2); // disconnect mysql_close();
So, the test was very simple - simultaneously run files in different browsers. For a different type of semaphore, you must use different logic and functions