簡單的說明
可能很少情況會使用php來操控共享記憶體,一方面在記憶體的控制上,mc已經提供了一套很好的方式,另一方面,自己來操控記憶體的難度較大,記憶體的讀寫與轉存,包括後面可能會用到的儲存策略,要是沒有一定計算機組成原理的基礎,想做這些不是一件容易的事情。那為什麼還要使用它呢?如果我想進行管道通訊,為其它的應用服務準備資料;我想建立自己的資料快取體系,使用mc有點大炮打蒼蠅的感覺。那麼shmop會是乙個選擇,當然,在操作記憶體前,一定要謹慎。
系統要求
shmop系列函式只是在unix/linux下可用,可以通過命令:
plain**
ipcs -m
來檢視當前的共享記憶體使用情況。其中,各個部分解釋如下:
key :共享記憶體的唯一的key值,共享記憶體通過該key來判斷你讀取的是哪一塊記憶體。
shmid:當使用key來獲取記憶體時,你獲得的是這個id的值。它作為你操作記憶體塊的標識。
owner:建立該共享記憶體塊的使用者
perms:該共享記憶體的讀寫許可權,8禁止,可以是777,與檔案的讀寫許可權一致。
bytes:該記憶體塊的大小
nattch:連線該記憶體塊的程序數
status:當前狀態,如:dest,即將刪除等。
使用示例
具體的使用說明,在php手冊中有詳細介紹,這裡不進行贅述。這裡將寫一些簡單的操作例子。
寫入
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**
<?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可以不要,因為你很少會從從機上讀取資料)。那麼好了,我們選擇其中一種來做吧。
主機傳送
php**
<?php
/**
* 共享記憶體操作,支援遠端記憶體同步。
使用的時候,進行:
php**
pshmop::write();
pshmop::write();
pshmop::write();
pshmop::send();
ps:為了支援多個更新一次傳遞的原則,以上便是舉例。
從機監聽
php**
<?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等,但並不是說這些策略就是好的。實際情況中,根據具體的業務需求,來組織相應的策略。最常見的,我們是將從資料庫查詢時間長的、獲取資料耗時(從其它機器上獲取)、計算耗時的、需要及時使用的放入記憶體中。
這部分的**就不寫了,希望有所幫助。
**自: 作者 tubaluer
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...