php實(shí)現(xiàn)讀取內(nèi)存順序號

字號:


    這篇文章主要介紹了php實(shí)現(xiàn)讀取內(nèi)存順序號,十分的簡單實(shí)用,需要的朋友可以參考下
    只是做記錄,osc本站應(yīng)該有重復(fù)的
    semWrapper.class.php
    /*
    * 信號量(Semaphore)。
    * 這是一個(gè)包裝類,用于解決不同平臺(tái)下對“信號量”的不同實(shí)現(xiàn)方式。
    * 目前這個(gè)類只是象征性的,在 Windows 平臺(tái)下實(shí)際是空跑(并沒有真的實(shí)現(xiàn)互斥)。
    */
    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
    /*
    * 順序號發(fā)生器。
    */
    class SeqGenerator
    {
    const SHM_KEY = 1;
    /**
    * 對順序號發(fā)生器進(jìn)行初始化。
    * 僅在服務(wù)器啟動(dòng)后的第一次調(diào)用有效,此后再調(diào)用此方法沒有實(shí)際作用。
    * @param int $start 產(chǎn)生順序號的起始值。
    * @return boolean 返回 true 表示成功。
    */
    static public function init( $start = 1 )
    {
    // 通過信號量實(shí)現(xiàn)互斥,避免對共享內(nèi)存的訪問沖突
    $sw = new SemWrapper;
    if ( ! $sw->acquire() ) {
    return false;
    }
    // 打開共享內(nèi)存
    $shm_id = shmop_open( self::SHM_KEY, 'n', 0644, 4 );
    if ( empty($shm_id) ) {
    // 因使用了 'n' 模式,如果無法打開共享內(nèi)存,可以認(rèn)為該共享內(nèi)存已經(jīng)創(chuàng)建,無需再次初始化
    $sw->release();
    return true;
    }
    // 在共享內(nèi)存中寫入初始值
    $size = shmop_write( $shm_id, pack( 'L', $start ), 0 );
    if ( $size != 4 ) {
    shmop_close( $shm_id );
    $sw->release();
    return false;
    }
    // 關(guān)閉共享內(nèi)存,釋放信號量
    shmop_close( $shm_id );
    $sw->release();
    return true;
    }
    /**
    * 產(chǎn)生下一個(gè)順序號。
    * @return int 產(chǎn)生的順序號
    */
    static public function next()
    {
    // 通過信號量實(shí)現(xiàn)互斥,避免對共享內(nèi)存的訪問沖突
    $sw = new SemWrapper;
    if ( ! $sw->acquire() ) {
    return 0;
    }
    // 打開共享內(nèi)存
    $shm_id = shmop_open( self::SHM_KEY, 'w', 0, 0 );
    if ( empty($shm_id) ) {
    $sw->release();
    return 0;
    }
    // 從共享內(nèi)存中讀出順序號
    $data = shmop_read( $shm_id, 0, 4 );
    if ( empty($data) ) {
    $sw->release();
    return 0;
    }
    $arr = unpack( 'L', $data );
    $seq = $arr[1];
    // 把下一個(gè)順序號寫入共享內(nèi)存
    $size = shmop_write( $shm_id, pack( 'L', $seq + 1 ), 0 );
    if ( $size != 4 ) {
    $sw->release();
    return 0;
    }
    // 關(guān)閉共享內(nèi)存,釋放信號量
    shmop_close( $shm_id );
    $sw->release();
    return $seq;
    }
    }
    page.php
    //使用方法
    $seq = SeqGenerator::next();
    var_dump($seq);
    以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。