PHP共享内存用法实例分析
本文实例讲述了PHP共享内存用法。分享给大家供大家参考,具体如下:
共享内存主要用于进程间通信
php中的共享内存有两套扩展可以实现
1、shmop 编译时需要开启--enable-shmop参数
实例:
$shm_key=ftok(__FILE__,'t'); /** 开辟一块共享内存 int$key,string$flags,int$mode,int$size $flags:a:访问只读内存段 c:创建一个新内存段,或者如果该内存段已存在,尝试打开它进行读写 w:可读写的内存段 n:创建一个新内存段,如果该内存段已存在,则会失败 $mode:八进制格式0655 $size:开辟的数据大小字节 */ $shm_id=shmop_open($shm_key,"c",0644,1024); /** *写入数据数据必须是字符串格式,最后一个指偏移量 *注意:偏移量必须在指定的范围之内,否则写入不了 * */ $size=shmop_write($shm_id,'songjiankang',0); echo"writeinto{$size}"; #读取的范围也必须在申请的内存范围之内,否则失败 $data=shmop_read($shm_id,0,100); var_dump($data); #删除只是做一个删除标志位,同时不在允许新的进程进程读取,当在没有任何进程读取时系统会自动删除 shmop_delete($shm_id); #关闭该内存段 shmop_close($shm_id);
2、用Semaphore扩展中的sem类函数(用起来更方便,类似key-value格式)
//Getthefiletokenkey $key=ftok(__DIR__,'a'); //创建一个共享内存 $shm_id=shm_attach($key,1024,777);//resourcetype if($shm_id===false){ die('Unabletocreatethesharedmemorysegment'); } #设置一个值 shm_put_var($shm_id,111,'value'); #删除一个key //shm_remove_var($shm_id,111); #获取一个值 $value=shm_get_var($shm_id,111); var_dump($value); #检测一个key是否存在 //var_dump(shm_has_var($shm_id,111)); #从系统中移除 shm_remove($shm_id); #关闭和共享内存的连接 shm_detach($shm_id);
注意:这两种方式不通用的
一个用共享内存和信号量实现的消息队列
/** *使用共享内存和信号量实现 * *支持多进程,支持各种数据类型的存储 *注:完成入队或出队操作,尽快使用unset(),以释放临界区 * */ classShmQueue { private$maxQSize=0;//队列最大长度 private$front=0;//队头指针 private$rear=0;//队尾指针 private$blockSize=256;//块的大小(byte) private$memSize=25600;//最大共享内存(byte) private$shmId=0; private$filePtr='./shmq.ptr'; private$semId=0; publicfunction__construct() { $shmkey=ftok(__FILE__,'t'); $this->shmId=shmop_open($shmkey,"c",0644,$this->memSize); $this->maxQSize=$this->memSize/$this->blockSize; //申請一个信号量 $this->semId=sem_get($shmkey,1); sem_acquire($this->semId);//申请进入临界区 $this->init(); } privatefunctioninit() { 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]; } } } publicfunctiongetLength() { return(($this->rear-$this->front+$this->memSize)%($this->memSize))/ $this->blockSize; } publicfunctionenQueue($value) { if($this->ptrInc($this->rear)==$this->front){//队满 returnfalse; } $data=$this->encode($value); shmop_write($this->shmId,$data,$this->rear); $this->rear=$this->ptrInc($this->rear); returntrue; } publicfunctiondeQueue() { if($this->front==$this->rear){//队空 returnfalse; } $value=shmop_read($this->shmId,$this->front,$this->blockSize-1); $this->front=$this->ptrInc($this->front); return$this->decode($value); } privatefunctionptrInc($ptr) { return($ptr+$this->blockSize)%($this->memSize); } privatefunctionencode($value) { $data=serialize($value)."__eof"; echo''; echostrlen($data); echo''; echo$this->blockSize-1; echo''; if(strlen($data)>$this->blockSize-1){ thrownewException(strlen($data)."isoverloadblocksize!"); } return$data; } privatefunctiondecode($value) { $data=explode("__eof",$value); returnunserialize($data[0]); } publicfunction__destruct() { $data=$this->front.'|'.$this->rear; file_put_contents($this->filePtr,$data); sem_release($this->semId);//出临界区,释放信号量 } } /* *//进队操作$shmq=newShmQueue();$data='testdata';$shmq->enQueue($data); *unset($shmq);//出队操作$shmq=newShmQueue();$data=$shmq->deQueue(); *unset($shmq); */
linux下用ipc命令查看,用ipcrm命令可以删除
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP基本语法入门教程》、《PHP错误与异常处理方法总结》、《php程序设计算法总结》及《php面向对象程序设计入门教程》
希望本文所述对大家PHP程序设计有所帮助。