note 116666 added to function.sem-acquire

From: Date: Fri, 06 Feb 2015 21:25:03 +0000
Subject: note 116666 added to function.sem-acquire
Groups: php.notes 
Request: Send a blank email to php-notes+get-201659@lists.php.net to get a copy of this message
If you need non-blocking semaphores, here is an example how you may implement it. Use a shared memory variable to mark whether or not a lock exists and then use a semaphore around operations against that variable. I'll call my shared variable as 'token'. <?php echo '<pre>'; $resourceSemaphore = sem_get(7); $tokenSemaphore = sem_get(8); $tokenValue = shm_attach(9, 100); function myEcho($v) { echo microtime() . ' ' . $v . "\n"; } // sem_remove($resourceSemaphore); // sem_remove($tokenSemaphore); // exit(); function try_lock() { global $resourceSemaphore, $tokenSemaphore, $tokenValue; myEcho('begin try_lock()'); myEcho('acquire token semaphore'); sem_acquire($tokenSemaphore); myEcho(' token semaphore acquired'); $tmp = shm_get_var($tokenValue, 6); myEcho(' token value: ' . var_export($tmp, true)); $exit = $tmp; if (!$exit) { $tmp = shm_put_var($tokenValue, 6, true); $tmp = shm_get_var($tokenValue, 6); myEcho(' token new value: ' . var_export($tmp, true)); } myEcho('release token semaphore'); sem_release($tokenSemaphore); if ($exit) return false; myEcho('acquire resource semaphore'); sem_acquire($resourceSemaphore); myEcho(' resource semaphore acquired'); return true; } function release() { global $resourceSemaphore, $tokenSemaphore, $tokenValue; myEcho('release resource semaphore'); sem_release($resourceSemaphore); myEcho('acquire token semaphore'); sem_acquire($tokenSemaphore); myEcho(' token semaphore acquired'); $tmp = shm_get_var($tokenValue, 6); myEcho(' token value: ' . var_export($tmp, true)); $tmp = shm_put_var($tokenValue, 6, false); $tmp = shm_get_var($tokenValue, 6); myEcho(' token new value: ' . var_export($tmp, true)); myEcho('release token semaphore'); sem_release($tokenSemaphore); } for ($triesLeft = 5; $triesLeft > 0 && !try_lock(); $triesLeft--) { myEcho('failed to acquire resource'); myEcho('wait for 1 sec'); sleep(1); myEcho('try again'); } myEcho(' access the resource for 4 sec'); //paste here your code, accessing your resource sleep(4); release(); myEcho('the end'); ?> When I execute this script in two parallel instances, I get the following output: -------(first instance)---------------------------------------- ... 482 begin try_lock() ... 482 acquire token semaphore ... 482 token semaphore acquired ... 482 token value: false ... 482 token new value: true ... 482 release token semaphore ... 482 acquire resource semaphore ... 482 resource semaphore acquired ... 482 access the resource for 4 sec ... 486 release resource semaphore ... 486 acquire token semaphore ... 486 token semaphore acquired ... 486 token value: true ... 486 token new value: false ... 486 release token semaphore ... 486 the end -------(second instance)---------------------------------------- ... 485 begin try_lock() ... 485 acquire token semaphore ... 485 token semaphore acquired ... 485 token value: true ... 485 release token semaphore ... 485 failed to acquire resource ... 485 wait for 1 sec ... ... 486 wait for 1 sec ... 487 try again ... 487 begin try_lock() ... 487 acquire token semaphore ... 487 token semaphore acquired ... 487 token value: false ... 487 token new value: true ... 487 release token semaphore ... 487 acquire resource semaphore ... 487 resource semaphore acquired ... 487 access the resource for 4 sec ... 491 release resource semaphore ... 491 acquire token semaphore ... 491 token semaphore acquired ... 491 token value: true ... 491 token new value: false ... 491 release token semaphore ... 491 the end ---- Server IP: 72.52.91.14 Probable Submitter: 109.110.94.63 ---- Manual Page -- http://php.net/manual/en/function.sem-acquire.php Edit -- https://master.php.net/note/edit/116666 Del: integrated -- https://master.php.net/note/delete/116666/integrated Del: useless -- https://master.php.net/note/delete/116666/useless Del: bad code -- https://master.php.net/note/delete/116666/bad+code Del: spam -- https://master.php.net/note/delete/116666/spam Del: non-english -- https://master.php.net/note/delete/116666/non-english Del: in docs -- https://master.php.net/note/delete/116666/in+docs Del: other reasons-- https://master.php.net/note/delete/116666 Reject -- https://master.php.net/note/reject/116666 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#201659) next »