课程咨询 :13623629309

太原PHP培训 > 达内新闻 > PHP给你带来的惊喜(二)
  • PHP给你带来的惊喜(二)

    发布:公众账号      来源:公众账号      时间:2016-11-14

  • PHP给你带来的惊喜(二)

    分布式、CAP理论、高可用、最终一致性、强一致性、因果一致性、异地多活... 听多了,这次给大家带来的是一篇单机共享内存的使用场景和分析,刷新你的胃口!!!

    第四个参数($size)

    内存段大小,以字节为单位。在写入一个内存段之前,您必须在它之上分配适当的字节数。

    此函数返回一个 ID 编号,其他函数可使用该 ID 编号操作该共享内存段。这个 ID 是共享内存访问 ID,与系统 ID 不同,它以参数的形式传递。请注意不要混淆这两者。如果失败,shmop_open 将返回 FALSE

    shmop_open成功后,使用ipcs -m, 可以查看到刚刚创建的内存段,注意 申请的内存段有严格的权限,比如用root用户申请的,普通用户就无权访问

    [[test@test]~/temp\]$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00924660 0 root 666 8 104 0x00000000 294915 root 666 787528456 1 dest 0x68410e9f 753668 test 644 1024 0

    2. 向内存段写入数据

    使用 shmop_write 函数向共享内存块写入数据。此函数的使用很简单,它仅接受 3 个参数,如下所示。

    //这里shmid可以延用上一段代码返回的shmid

    $shmid = shmop_open(ftok(__FILE__,'h), 'c', 0644, 1024); shmop_write($shmid, "Hello World!", 0); ?>

    这个函数类似于 fwrite 函数, 在这里有三个参数。

    第一个参数($shmid):是 shmop_open 返回的 ID,它识别您操作的共享内存块。

    第二个参数($data):是您希望存储的数据。

    第三个参数($offset):是您希望开始写入的位置。默认情况下,我们始终使用 0 来表示开始写入的位置。

    返回结果:此函数在失败时会返回 FALSE,在成功时会返回写入的字节数。

    3. 从内存段读取数据

    从共享内存段读取数据很简单。您只需要一个打开的内存段和 shmop_read 函数,它接受三个参数,如下所示:

    第一个参数($shmid):是 shmop_open 返回的 ID,它识别您操作的共享内存块。

    第二个参数($start):是您希望从内存段读取的位置,这个参数可以始终为0 表示数据的开头

    第三个参数($count):是您希望读取的字节数。一般情况下我们用shmop_size($shmid),以便完整的读取它。

    4. 删除内存段

    shmop_delete 该函数只接收一个参数,如下所示:

    $shmid = shmop_open(ftok(\__FILE_\_,'h), 'c', 0644, 1024);

    shmop_delete($shmid);

    ?>

    其实这个函数不会实际删除该内存段。它将该内存段标记为删除状态,因为共享内存段在有其他进程正在使用它时无法被删除。shmop_delete 函数将该内存段标记为删除,阻止任何其他进程打开它。要删除它,我们需要关闭该内存段。

    5. 关闭内存段

    打开一个共享内存段会附加到它。附加该内存段之后,我们可在其中进行读取和写入,但完成操作后,我们必须从它解除。

    共享内存的原子操作 - 信号控制

    针对共享内存的写操作本身不是原子性的,那么当我们大量并发进行读写的时候,怎么保证原子性呢,这里要引入信号量进行控制。

    PHP 也提供了内置扩展 sysvsem ,其实我们在看sysvsem 提供的一系列sem_*的方法的时候,就会想到,这和上面提到的shmop_*有什么区别呢,我们来看官房文档中的这一个解释:PHP already had a shared memory extension (sysvshm) written by Christian Cartus , unfortunately this extension was designed with PHP only in mind and offers high level features which are extremely bothersome for basic SHM we had in mind.

    也就是说:sysvshm 扩展提供的方法在存储之前对用户的数据进行serialize处理,这里就导致这个存储的数据是无法与其它语言共享的,这一系列方法是php only的方法。

    引入信号控制之后的示例:

    共享内存的操作是非常快的,在本地想要模拟实现写入冲突是非常困难的,但是本地想模拟实现写入冲突实际上是非常难的(考虑到计算机的执行速度)。在本地测试中,使用 for 循环操作时如果不使用shmop_close 关闭资源会出现无法打开共享内存的错误警告。这应该是因为正在共享内存被上一次操作占用中还没有释放导致。

    共享内存,memcache,文件的读写速度对比。

    以下是同时读写1k的数据读写100000次的时间对比:

    (s)(s)

    memcache7.88.11

    文件2.63.2

    shm0.10.07

    共享内存的使用场景,想了很久,结合自己曾经做过的项目,发现能用到共享内存的地方比较少。

    好了,今天就给大家讲这么多吧,喜欢我的内容可以关注或者分享(微信公众平台:tytedu)选择太原达内培训,不再孤军奋战,轻轻松松做IT高薪白领。太原达内培训带领有明确目标的学子迈向成功之路!

上一篇:PHP给你带来的惊喜(一)

下一篇:Monolog-PHP日志类库解密

最新开班日期  |  更多

php高级开发名企定制班(剩2个名额)

php高级开发名企定制班(剩2个名额)

开班日期:12-29

php高级开发周末班(剩5个名额)

php高级开发周末班(剩5个名额)

开班日期:12-29

php高级开发免费试听(剩5个名额)

php高级开发免费试听(剩5个名额)

开班日期:12-29

更多高级开发工程师精品班

更多高级开发工程师精品班

开班日期:12-29

  • 地址:山西省太原市小店区学府街长治路高新国际A座24层
  • 课程培训电话:13623629309     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56