zoukankan      html  css  js  c++  java
  • php操作共享内存shmop类及简单使用测试(代码)

    SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段。在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码。可以使用 3 个方法进行处理:读、写和删除。从该类中简单地实例化一个对象,可以控制打开的共享内存段。

    类对象和测试代码

    <?php
    //类对象
    namespace SimpleSHM;
    
    class Block
    {
        /**
         * Holds the system id for the shared memory block
         *
         * @var int
         * @access protected
         */
        protected $id;
    
        /**
         * Holds the shared memory block id returned by shmop_open
         *
         * @var int
         * @access protected
         */
        protected $shmid;
    
        /**
         * Holds the default permission (octal) that will be used in created memory blocks
         *
         * @var int
         * @access protected
         */
        protected $perms = 0644;
    
        /**
         * Shared memory block instantiation
         *
         * In the constructor we'll check if the block we're going to manipulate
         * already exists or needs to be created. If it exists, let's open it.
         *
         * @access public
         * @param string $id (optional) ID of the shared memory block you want to manipulate
         */
        public function __construct($id = null)
        {
            if($id === null) {
                $this->id = $this->generateID();
            } else {
                $this->id = $id;
            }
    
            if($this->exists($this->id)) {
                $this->shmid = shmop_open($this->id, "w", 0, 0);
            }
        }
    
        /**
         * Generates a random ID for a shared memory block
         *
         * @access protected
         * @return int System V IPC key generated from pathname and a project identifier
         */
        protected function generateID()
        {
            $id = ftok(__FILE__, "b");
            return $id;
        }
    
        /**
         * Checks if a shared memory block with the provided id exists or not
         *
         * In order to check for shared memory existance, we have to open it with
         * reading access. If it doesn't exist, warnings will be cast, therefore we
         * suppress those with the @ operator.
         *
         * @access public
         * @param string $id ID of the shared memory block you want to check
         * @return boolean True if the block exists, false if it doesn't
         */
        public function exists($id)
        {
            $status = @shmop_open($id, "a", 0, 0);
            return $status;
        }
    
        /**
         * Writes on a shared memory block
         *
         * First we check for the block existance, and if it doesn't, we'll create it. Now, if the
         * block already exists, we need to delete it and create it again with a new byte allocation that
         * matches the size of the data that we want to write there. We mark for deletion,  close the semaphore
         * and create it again.
         *
         * @access public
         * @param string $data The data that you wan't to write into the shared memory block
         */
        public function write($data)
        {
            $size = mb_strlen($data, 'UTF-8');
    
            if($this->exists($this->id)) {
                shmop_delete($this->shmid);
                shmop_close($this->shmid);
                $this->shmid = shmop_open($this->id, "c", $this->perms, $size);
                shmop_write($this->shmid, $data, 0);
            } else {
                $this->shmid = shmop_open($this->id, "c", $this->perms, $size);
                shmop_write($this->shmid, $data, 0);
            }
        }
    
        /**
         * Reads from a shared memory block
         *
         * @access public
         * @return string The data read from the shared memory block
         */
        public function read()
        {
            $size = shmop_size($this->shmid);
            $data = shmop_read($this->shmid, 0, $size);
    
            return $data;
        }
    
        /**
         * Mark a shared memory block for deletion
         *
         * @access public
         */
        public function delete()
        {
            shmop_delete($this->shmid);
        }
    
        /**
         * Gets the current shared memory block id
         *
         * @access public
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * Gets the current shared memory block permissions
         *
         * @access public
         */
        public function getPermissions()
        {
            return $this->perms;
        }
    
        /**
         * Sets the default permission (octal) that will be used in created memory blocks
         *
         * @access public
         * @param string $perms Permissions, in octal form
         */
        public function setPermissions($perms)
        {
            $this->perms = $perms;
        }
    
        /**
         * Closes the shared memory block and stops manipulation
         *
         * @access public
         */
        public function __destruct()
        {
            shmop_close($this->shmid);
        }
    }
    <?php
    //测试使用代码
    namespace SimpleSHMTest;
    
    use SimpleSHMBlock;
    
    class BlockTest extends PHPUnit_Framework_TestCase
    {
        public function testIsCreatingNewBlock()
        {
            $memory = new Block;
            $this->assertInstanceOf('Simple\SHM\Block', $memory);
    
            $memory->write('Sample');
            $data = $memory->read();
            $this->assertEquals('Sample', $data);
        }
    
        public function testIsCreatingNewBlockWithId()
        {
            $memory = new Block(897);
            $this->assertInstanceOf('Simple\SHM\Block', $memory);
            $this->assertEquals(897, $memory->getId());
    
            $memory->write('Sample 2');
            $data = $memory->read();
            $this->assertEquals('Sample 2', $data);
        }
    
        public function testIsMarkingBlockForDeletion()
        {
            $memory = new Block(897);
            $memory->delete();
            $data = $memory->read();
            $this->assertEquals('Sample 2', $data);
        }
    
        public function testIsPersistingNewBlockWithoutId()
        {
            $memory = new Block;
            $this->assertInstanceOf('Simple\SHM\Block', $memory);
            $memory->write('Sample 3');
            unset($memory);
    
            $memory = new Block;
            $data = $memory->read();
            $this->assertEquals('Sample 3', $data);
        }
    }

    额外说明

    <?php
     
    $memory = new SimpleSHM;
    $memory->write('Sample');
    echo $memory->read();
     
    ?>

    请注意,上面代码里没有为该类传递一个 ID。如果没有传递 ID,它将随机选择一个编号并打开该编号的新内存段。我们可以以参数的形式传递一个编号,供构造函数打开现有的内存段,或者创建一个具有特定 ID 的内存段,如下

    <?php
     
    $new = new SimpleSHM(897);
    $new->write('Sample');
    echo $new->read();
     
    ?>

    神奇的方法 __destructor 负责在该内存段上调用 shmop_close 来取消设置对象,以与该内存段分离。我们将这称为 “SimpleSHM 101”。现在让我们将此方法用于更高级的用途:使用共享内存作为存储。存储数据集需要序列化,因为数组或对象无法存储在内存中。尽管这里使用了 JSON 来序列化,但任何其他方法(比如 XML 或内置的 PHP 序列化功能)也已足够。如下

    <?php
     
    require('SimpleSHM.class.php');
     
    $results = array(
        'user' => 'John',
        'password' => '123456',
        'posts' => array('My name is John', 'My name is not John')
    );
     
    $data = json_encode($results);
     
    $memory = new SimpleSHM;
    $memory->write($data);
    $storedarray = json_decode($memory->read());
     
    print_r($storedarray);
     
    ?>

    我们成功地将一个数组序列化为一个 JSON 字符串,将它存储在共享内存块中,从中读取数据,去序列化 JSON 字符串,并显示存储的数组。这看起来很简单,但请想象一下这个代码片段带来的可能性。您可以使用它存储 Web 服务请求、数据库查询或者甚至模板引擎缓存的结果。在内存中读取和写入将带来比在磁盘中读取和写入更高的性能。

    使用此存储技术不仅对缓存有用,也对应用程序之间的数据交换也有用,只要数据以两端都可读的格式存储。不要低估共享内存在 Web 应用程序中的力量。可采用许多不同的方式来巧妙地实现这种存储,惟一的限制是开发人员的创造力和技能。

  • 相关阅读:
    JQuery
    如何垂直居中一个浮动元素
    Bootstrap概述
    浮动元素的水平居中
    图(Prime算法、 Kruskal算法、Dijkstra算法、Floyd算法、AOV网)
    排序(插入排序、选择排序、交换排序、二路归并排序、基数排序、外部排序)
    实验二 Scala编程初级实践
    数据类型、运算符
    用栈求前缀表达式值
    用栈求后缀表达式地的值
  • 原文地址:https://www.cnblogs.com/wt645631686/p/9146258.html
Copyright © 2011-2022 走看看