只是做記錄,osc本站應該有重復的
semWrapper.class.php
/* * 信號量(Semaphore)。 * 這是一個包裝類,用於解決不同平台下對“信號量”的不同實現方式。 * 目前這個類只是象征性的,在 Windows 平台下實際是空跑(並沒有真的實現互斥)。 */ class SemWrapper { private $hasSemSupport; private $sem; const SEM_KEY = 1; public function __construct() { $this->hasSemSupport = function_exists( 'sem_get' ); if ( $this->hasSemSupport ) { $this->sem = sem_get( self::SEM_KEY ); } } public function acquire() { if ( $this->hasSemSupport ) { return sem_acquire( $this->sem ); } return true; } public function release() { if ( $this->hasSemSupport ) { return sem_release( $this->sem ); } return true; } }
SeqGenerator.class.php
/* * 順序號發生器。 */ class SeqGenerator { const SHM_KEY = 1; /** * 對順序號發生器進行初始化。 * 僅在服務器啟動後的第一次調用有效,此後再調用此方法沒有實際作用。 * @param int $start 產生順序號的起始值。 * @return boolean 返回 true 表示成功。 */ static public function init( $start = 1 ) { // 通過信號量實現互斥,避免對共享內存的訪問沖突 $sw = new SemWrapper; if ( ! $sw->acquire() ) { return false; } // 打開共享內存 $shm_id = shmop_open( self::SHM_KEY, 'n', 0644, 4 ); if ( empty($shm_id) ) { // 因使用了 'n' 模式,如果無法打開共享內存,可以認為該共享內存已經創建,無需再次初始化 $sw->release(); return true; } // 在共享內存中寫入初始值 $size = shmop_write( $shm_id, pack( 'L', $start ), 0 ); if ( $size != 4 ) { shmop_close( $shm_id ); $sw->release(); return false; } // 關閉共享內存,釋放信號量 shmop_close( $shm_id ); $sw->release(); return true; } /** * 產生下一個順序號。 * @return int 產生的順序號 */ static public function next() { // 通過信號量實現互斥,避免對共享內存的訪問沖突 $sw = new SemWrapper; if ( ! $sw->acquire() ) { return 0; } // 打開共享內存 $shm_id = shmop_open( self::SHM_KEY, 'w', 0, 0 ); if ( empty($shm_id) ) { $sw->release(); return 0; } // 從共享內存中讀出順序號 $data = shmop_read( $shm_id, 0, 4 ); if ( empty($data) ) { $sw->release(); return 0; } $arr = unpack( 'L', $data ); $seq = $arr[1]; // 把下一個順序號寫入共享內存 $size = shmop_write( $shm_id, pack( 'L', $seq + 1 ), 0 ); if ( $size != 4 ) { $sw->release(); return 0; } // 關閉共享內存,釋放信號量 shmop_close( $shm_id ); $sw->release(); return $seq; } }
page.php
//使用方法 $seq = SeqGenerator::next(); var_dump($seq);
以上所述就是本文的全部內容了,希望大家能夠喜歡。