PHP共享內(nèi)存用法實(shí)例分析
本文實(shí)例講述了PHP共享內(nèi)存用法。分享給大家供大家參考,具體如下:
共享內(nèi)存主要用于進(jìn)程間通信
php中的共享內(nèi)存有兩套擴(kuò)展可以實(shí)現(xiàn)
1、shmop 編譯時(shí)需要開啟 --enable-shmop 參數(shù)
實(shí)例:
$shm_key = ftok(__FILE__, 't'); /** 開辟一塊共享內(nèi)存 int $key , string $flags , int $mode , int $size $flags: a:訪問只讀內(nèi)存段 c:創(chuàng)建一個(gè)新內(nèi)存段,或者如果該內(nèi)存段已存在,嘗試打開它進(jìn)行讀寫 w:可讀寫的內(nèi)存段 n:創(chuàng)建一個(gè)新內(nèi)存段,如果該內(nèi)存段已存在,則會(huì)失敗 $mode: 八進(jìn)制格式 0655 $size: 開辟的數(shù)據(jù)大小 字節(jié) */ $shm_id = shmop_open($shm_key, "c", 0644, 1024); /** * 寫入數(shù)據(jù) 數(shù)據(jù)必須是字符串格式 , 最后一個(gè)指偏移量 * 注意:偏移量必須在指定的范圍之內(nèi),否則寫入不了 * */ $size = shmop_write($shm_id, 'songjiankang', 0); echo "write into {$size}"; #讀取的范圍也必須在申請(qǐng)的內(nèi)存范圍之內(nèi),否則失敗 $data = shmop_read($shm_id, 0, 100); var_dump($data); #刪除 只是做一個(gè)刪除標(biāo)志位,同時(shí)不在允許新的進(jìn)程進(jìn)程讀取,當(dāng)在沒有任何進(jìn)程讀取時(shí)系統(tǒng)會(huì)自動(dòng)刪除 shmop_delete($shm_id); #關(guān)閉該內(nèi)存段 shmop_close($shm_id);
2、用 Semaphore 擴(kuò)展中的 sem 類函數(shù) (用起來(lái)更方便,類似 key-value 格式)
// Get the file token key $key = ftok(__DIR__, 'a'); // 創(chuàng)建一個(gè)共享內(nèi)存 $shm_id = shm_attach($key, 1024, 777); // resource type if ($shm_id === false) { die('Unable to create the shared memory segment'); } #設(shè)置一個(gè)值 shm_put_var($shm_id, 111, 'value'); #刪除一個(gè)key //shm_remove_var($shm_id, 111); #獲取一個(gè)值 $value = shm_get_var($shm_id, 111); var_dump($value); #檢測(cè)一個(gè)key是否存在 // var_dump(shm_has_var($shm_id, 111)); #從系統(tǒng)中移除 shm_remove($shm_id); #關(guān)閉和共享內(nèi)存的連接 shm_detach($shm_id);
注意:這兩種方式不通用的
一個(gè)用共享內(nèi)存和信號(hào)量實(shí)現(xiàn)的消息隊(duì)列
/** * 使用共享內(nèi)存和信號(hào)量實(shí)現(xiàn) * * 支持多進(jìn)程, 支持各種數(shù)據(jù)類型的存儲(chǔ) * 注: 完成入隊(duì)或出隊(duì)操作,盡快使用unset(), 以釋放臨界區(qū) * */ class ShmQueue { private $maxQSize = 0; // 隊(duì)列最大長(zhǎng)度 private $front = 0; // 隊(duì)頭指針 private $rear = 0; // 隊(duì)尾指針 private $blockSize = 256; // 塊的大小(byte) private $memSize = 25600; // 最大共享內(nèi)存(byte) private $shmId = 0; private $filePtr = './shmq.ptr'; private $semId = 0; public function __construct () { $shmkey = ftok(__FILE__, 't'); $this->shmId = shmop_open($shmkey, "c", 0644, $this->memSize); $this->maxQSize = $this->memSize / $this->blockSize; // 申請(qǐng)一個(gè)信號(hào)量 $this->semId = sem_get($shmkey, 1); sem_acquire($this->semId); // 申請(qǐng)進(jìn)入臨界區(qū) $this->init(); } private function init () { if (file_exists($this->filePtr)) { $contents = file_get_contents($this->filePtr); $data = explode('|', $contents); if (isset($data[0]) && isset($data[1])) { $this->front = (int) $data[0]; $this->rear = (int) $data[1]; } } } public function getLength () { return (($this->rear - $this->front + $this->memSize) % ($this->memSize)) / $this->blockSize; } public function enQueue ($value) { if ($this->ptrInc($this->rear) == $this->front) { // 隊(duì)滿 return false; } $data = $this->encode($value); shmop_write($this->shmId, $data, $this->rear); $this->rear = $this->ptrInc($this->rear); return true; } public function deQueue () { if ($this->front == $this->rear) { // 隊(duì)空 return false; } $value = shmop_read($this->shmId, $this->front, $this->blockSize - 1); $this->front = $this->ptrInc($this->front); return $this->decode($value); } private function ptrInc ($ptr) { return ($ptr + $this->blockSize) % ($this->memSize); } private function encode ($value) { $data = serialize($value) . "__eof"; echo ''; echo strlen($data); echo ''; echo $this->blockSize - 1; echo ''; if (strlen($data) > $this->blockSize - 1) { throw new Exception(strlen($data) . " is overload block size!"); } return $data; } private function decode ($value) { $data = explode("__eof", $value); return unserialize($data[0]); } public function __destruct () { $data = $this->front . '|' . $this->rear; file_put_contents($this->filePtr, $data); sem_release($this->semId); // 出臨界區(qū), 釋放信號(hào)量 } } /* * // 進(jìn)隊(duì)操作 $shmq = new ShmQueue(); $data = 'test data'; $shmq->enQueue($data); * unset($shmq); // 出隊(duì)操作 $shmq = new ShmQueue(); $data = $shmq->deQueue(); * unset($shmq); */
linux下 用 ipc命令查看 ,用 ipcrm 命令可以刪除
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《PHP基本語(yǔ)法入門教程》、《PHP錯(cuò)誤與異常處理方法總結(jié)》、《php程序設(shè)計(jì)算法總結(jié)》及《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
相關(guān)文章
PHP5.5基于mysqli連接MySQL數(shù)據(jù)庫(kù)和讀取數(shù)據(jù)操作實(shí)例詳解
這篇文章主要介紹了PHP5.5基于mysqli連接MySQL數(shù)據(jù)庫(kù)和讀取數(shù)據(jù)操作,結(jié)合實(shí)例形式詳細(xì)分析了php5.5使用mysqli連接、讀取mysql數(shù)據(jù)庫(kù),以及PDO預(yù)處理相關(guān)操作技巧,需要的朋友可以參考下2019-02-02PHP實(shí)現(xiàn)的DES加密解密封裝類完整實(shí)例
這篇文章主要介紹了PHP實(shí)現(xiàn)的DES加密解密封裝類,結(jié)合完整實(shí)例形式分析了php DES加密解密封裝類的定義與使用技巧,需要的朋友可以參考下2017-04-04Laravel網(wǎng)站打開速度優(yōu)化的方法匯總
最近在學(xué)習(xí) Laravel 框架,自己做了個(gè)小站,總結(jié)了一些 Laravel 網(wǎng)站性能提升的方法。所以下面這篇文章主要給大家匯總介紹了關(guān)于Laravel網(wǎng)站打開速度優(yōu)化的一些方法,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-07-07簡(jiǎn)單概括PHP的字符串中單引號(hào)與雙引號(hào)的區(qū)別
這篇文章主要介紹了PHP的字符串中單引號(hào)與雙引號(hào)的區(qū)別,是PHP入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-05-05Warning:?require():?open_basedir?restriction?in?effect,
在linux服務(wù)器部署thinkphp5的時(shí)候PHP報(bào)了Warning:?require():?open_basedir?restriction?in?effect這個(gè)錯(cuò)誤,是因?yàn)榫W(wǎng)站目錄配置錯(cuò)誤,PHP不能引入其授權(quán)目錄上級(jí)及其以上的文件。下面詳細(xì)講解如何處理這個(gè)問題,需要的朋友可以參考下2022-11-11PHP實(shí)現(xiàn)ASCII碼與字符串相互轉(zhuǎn)換的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)ASCII碼與字符串相互轉(zhuǎn)換的方法,涉及php字符串的遍歷、替換、編碼轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2017-04-04PHP設(shè)計(jì)模式之模板方法模式定義與用法詳解
這篇文章主要介紹了PHP設(shè)計(jì)模式之模板方法模式,結(jié)合實(shí)例形式詳細(xì)分析了php設(shè)計(jì)模式中模板方法模式的概念、原理、定義、用法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-04-04