PHP共享記憶體的應用shmop系列

2021-08-26 02:03:35 字數 3090 閱讀 9414

簡單的說明

可能很少情況會使用php來操控共享記憶體,一方面在記憶體的控制上,mc已經提供了一套很好的方式,另一方面,自己來操控記憶體的難度較大,記憶體的讀寫與轉存,包括後面可能會用到的儲存策略,要是沒有一定計算機組成原理的基礎,想做這些不是一件容易的事情。那為什麼還要使用它呢?如果我想進行管道通訊,為其它的應用服務準備資料;我想建立自己的資料快取體系,使用mc有點大炮打蒼蠅的感覺。那麼shmop會是乙個選擇,當然,在操作記憶體前,一定要謹慎。

系統要求

shmop系列函式只是在unix/linux下可用,可以通過命令:

ipcs -m

來檢視當前的共享記憶體使用情況。其中,各個部分解釋如下:

key :共享記憶體的唯一的key值,共享記憶體通過該key來判斷你讀取的是哪一塊記憶體。

shmid:當使用key來獲取記憶體時,你獲得的是這個id的值。它作為你操作記憶體塊的標識。

owner:建立該共享記憶體塊的使用者

perms:該共享記憶體的讀寫許可權,8禁止,可以是777,與檔案的讀寫許可權一致。

bytes:該記憶體塊的大小

nattch:連線該記憶體塊的程序數

status:當前狀態,如:dest,即將刪除等。

使用示例

具體的使用說明,在php手冊中有詳細介紹,這裡不進行贅述。這裡將寫一些簡單的操作例子。

寫入

<?php /** * shmop共享記憶體操作示例 * @author monkee **/ $key = 0x4337b700; $size = 4096; $shmid = @shmop_open($key, 'c', 0644, $size); if($shmid === false) $data = '世界,你好!我將寫入很多的資料,你能罩得住麼?'; $length = shmop_write($shmid, pack('a*',$data), 0); if($length === false) @shmop_close($shmid); exit('succ'); ?>

讀取<?php /** * shmop共享記憶體操作示例 * @author monkee **/ $key = 0x4337b700; $size = 256; $shmid = @shmop_open($key, 'c', 0644, $size); if($shmid === false) $data = unpack('a*', shmop_read($shmid, 0, 256)); if($data === false) @shmop_close($shmid); exit($data[1]); ?>

這裡使用到了函式:pack() 這個函式用來將記憶體裡的內容轉化為二進位制內容,具體請檢視手冊內容。

多伺服器記憶體同步

已經在本地做好了這個服務,現在需要在多台伺服器上進行記憶體資料同步。雖然這個時候可以放棄共享記憶體的方式來處理資料了,然而你被要求需要這麼做。於是,同步我想不是問題,做好「主-從」的架構,我同步好的記憶體及時推送過去就可以了。然而,我是不是需要在從機上做乙個監聽程式呢?這樣的代價有點大,好的一點是,從機上有apache。也就是說可以使用http協議來進行通訊了。

同步策略

如何同步?看似無聊的問題,卻又產生了疑惑。同步資料唄,但是同步什麼資料!一種方式是主機的記憶體改變後,程式讀取所有記憶體資料然後傳送到從機進行同步;如果我只是更改一些簡單的操作位的話,那麼小的更新卻要引起整個記憶體塊的同步,似乎有些浪費。還有一種,是更新變化。將變化進行更新。這種比較複雜,因為你需要定義每一種操作的處理。幸運的是,你需要操作的資料並不多,還有,你要定義的操作也不多:write,delete(read可以不要,因為你很少會從從機上讀取資料)。那麼好了,我們選擇其中一種來做吧。

主機傳送

pshmop::write(); pshmop::write(); pshmop::write(); pshmop::send();

ps:為了支援多個更新一次傳遞的原則,以上便是舉例。

從機監聽

<?php /** * 共享記憶體遠端處理類 * 對從遠端傳輸到的資料進行處理、記憶體同步更新 * @author hufeng@ * @since 2011-08-11 **/ define('rshmop_sepe', "\r\n----------cksjfiowkjdfockjvnbbsdf----------\r\n"); class rshmop $result = array('succ' => 0, 'error' => 0); foreach($items as $k => $i) return $result; } static public function op($str) $body = substr($str, $p+1); $shmid = null; if($header['size'] > 0) if(!$shmid)'"; $em = exec($cmd); $em = preg_replace('/ +/', ' ', $em); $ems = explode(' ', $em); $header['size'] = intval($ems[4]); if($header['size'] == 0)else } $shmid = @shmop_open($header['key'], 'c', 0644, $header['size']); } if($header['ac'] == 'write') if($header['ac'] == 'delete') shmop_close($shmid); return 0; } }

如果遇到主機有而從機未有的資料塊(可能由網路問題造成,也可以有其它解決辦法),可以選擇delete然後再進行其它操作。

快取使用的策略

覺得使用mc代價有點高,可以自己來控制記憶體和使用。當然,小部分的資料可以容易使用,但是當資料多的時候,決定哪部分資料進入記憶體,哪部分資料進入硬碟都是值得商榷的。這也就是為什麼要提策略。

常見的策略無非是 fifo,lur,lar等,但並不是說這些策略就是好的。實際情況中,根據具體的業務需求,來組織相應的策略。最常見的,我們是將從資料庫查詢時間長的、獲取資料耗時(從其它機器上獲取)、計算耗時的、需要及時使用的放入記憶體中。

這部分的**就不寫了,希望有所幫助。

PHP共享記憶體的應用shmop系列

簡單的說明 可能很少情況會使用php來操控共享記憶體,一方面在記憶體的控制上,mc已經提供了一套很好的方式,另一方面,自己來操控記憶體的難度較大,記憶體的讀寫與轉存,包括後面可能會用到的儲存策略,要是沒有一定計算機組成原理的基礎,想做這些不是一件容易的事情。那為什麼還要使用它呢?如果我想進行管道通訊...

php 共享記憶體學習 shmop函式

問題 希望可以在程序間共享變數,為共享資料提供快速訪問 解決方案 除了可以使用apc模組,還可以用shmop或system v共享記憶體 1 建立鍵 2 將乙個可訪問的檔案路徑名轉換為乙個可供 shmop open 和其他系統vipc keys使用的整數,proj引數必須是乙個字串,這個引數其實就是...

shmop 系列函式使用 php共享記憶體

1 shmop 系列函式使用 使用shmop 系列函式 set time limit 0 shm key ftok file t shm id shmop open shm key,c 0655,1024 size shmop write shm id,hello world php eol,0 s...