php共享内存_使用PHP将数据集直接存储在共享内存中

php共享内存

总览

共享内存是在同一台计算机上的应用程序之间交换数据的有效方法。 一个进程可以创建其他进程可以访问的内存段,只要它分配了正确的权限即可。 每个段都有一个唯一的ID,称为shmid ,它指向其他进程可以操纵它的物理内存区域。 创建并获得适当的权限后,同一台计算机上的其他进程可以通过以下方式操纵这些段:读取,写入和删除。

这意味着用C编写的应用程序可以与其他语言编写的应用程序共享信息,例如Java™或PHP。 他们都可以共享信息,只要他们可以访问和理解该信息即可。 共享内存广泛用于大多数语言的实现中,因此访问应该不是问题。 至于了解信息,我们可以使用XML或JSON之类的标准格式。

共享内存的使用是进程之间数据交换的一种快速方法,主要是因为在创建段之后,没有内核参与传递数据。 这种方法通常称为进程间通信(IPC)。 其他IPC方法包括管道,消息队列,RPC和套接字。 当使用需要相互通信的应用程序生态系统时,这种在应用程序之间交换数据的快速而可靠的能力是无价的。 使用数据库在应用程序之间交换信息的常用方法通常会导致查询缓慢,甚至阻塞I / O,具体取决于生态系统的大小。 使用共享内存,没有I / O会拖慢开发人员的速度。

本文的建议很简单,了解如何使用PHP创建和操作共享内存段以及如何使用它们存储其他应用程序可以使用的数据集。 即使没有计划使用共享内存进行数据交换,它也是有益的,因为它允许应用程序避免I / O问题。 从Web服务数据缓存到会话共享,将数据集直接存储在内存中具有许多优点。 每个PHP开发人员都应该知道这是一个非常有用的概念。

共享内存和PHP

PHP和共享内存都有许多可用的扩展。 有了一些共享功能,并且无需安装任何扩展程序,开发人员便可以轻松地操作段。

建立区隔

共享内存功能类似于文件操作功能,但是您将不使用流,而是使用共享内存访问ID。 第一个示例是shmop_open函数,该函数允许您打开现有段或创建新段。 此函数非常类似于经典的fopen函数,该函数打开流以进行文件操作,并返回一个资源,该资源以后可被希望对该打开的流进行读写的其他函数使用。 让我们看一下清单1中的shmop_open

清单1. shmop_open函数
<?php

$systemid = 864; // System ID for the shared memory segment
$mode = "c"; // Access mode
$permissions = 0755; // Permissions for the shared memory segment
$size = 1024; // Size, in bytes, of the segment

$shmid = shmop_open($systemid, $mode, $permissions, $size);

?>

首先显示的是系统ID参数。 这是标识系统中共享内存段的数字。 第二个参数是访问模式,它与fopen函数的访问模式非常相似。 您可以通过四种不同的模式访问细分:

  • 模式“ a”,它使您可以访问只读段
  • 模式“ w”,允许您访问该段以进行读写
  • 模式“ c”,它将创建一个新的段,或者如果该段已经存在,请尝试打开以进行读写
  • 模式“ n”创建一个新的段,如果该段已经存在,则失败

第三个参数是该段的权限。 您必须在此处提供一个八进制值。

第四个参数提供段大小(以字节为单位)。 在写入段之前,必须在其上分配适当数量的字节。

请注意,此函数返回一个ID号,该ID号可与其他函数一起使用以操纵共享内存段。 此ID是共享内存访问ID,并且与作为参数传递的系统ID不同。 注意不要混淆两者。 失败时, shmop_open将返回FALSE。

写入细分

使用shmop_write函数可写入共享内存块。 此函数易于使用,仅接受三个参数。 如清单2所示,此函数易于使用,并且仅接受三个参数。

清单2.使用shmop_write写入共享内存块
<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);

?>

fwrite函数相似,它具有两个参数: fopen返回的打开的流资源和要写入的数据。 shmop_write函数就是这样做的。

第一个参数是shmop_open返回的ID, shmop_open标识您要操作的共享内存块。 第二个参数是要存储的数据,最后,第三个参数是要开始写入的位置。 默认情况下,我们始终在此处使用0从头开始写。 请注意,此函数在失败时返回FALSE,在成功时返回写入的字节数。

从细分中读取

从共享内存段读取很简单。 您需要的只是一个打开的段和shmop_read函数。 该函数接受一些参数,并且与fread类似地工作。 请参见清单3,以使用PHP读取文件的内容。

清单3.使用shmop_read读取文件的内容
<?php

$stream = fopen('file.txt', 'r+');
fwrite($stream, "Hello World!");
echo fread($stream, 11);

?>

读取共享内存段的内容类似,如清单4所示:

清单4.读取共享内存段的内容
<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);
echo shmop_read($shmid, 0, 11);

?>

在此处观察参数。 shmop_read函数将接受shmop_open返回的ID(我们已经知道),但它也接受其他两个参数。 第二个参数是您要从该段开始读取的位置; 而第三个是您要读取的字节数。 第二个参数可能始终为0,即数据的开头,但第三个参数可能会出现问题,因为我们可能不知道要读取多少字节。

这与fread函数中的行为非常相似,该函数接受两个参数: fopen返回的打开的流资源以及要从该流中读取多少字节。 使用filesize函数,该函数返回文件中的字节数以完整读取它。

幸运的是,与共享内存段一起使用时,类似于filesize函数, shmop_size函数返回段的字节filesize 。 参见清单5。

清单5. shmop_size函数返回段的字节大小
<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);

$size = shmop_size($shmid);
echo shmop_read($shmid, 0, $size);

?>

删除细分

我们学习了如何打开,写入和读取共享内存段。 要完成我们的CRUD课程,我们需要学习如何删除句段。 使用shmop_delete函数可以轻松完成此任务,该函数只需要一个参数:我们要删除的共享内存ID。

清单6. shmop_delete标记要删除的段
<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);
shmop_delete($shmid);

?>

这实际上并不会删除细分。 它标记了要删除的段,因为共享内存段无法在其他进程使用时删除。 shmop_delete函数将标记要删除的段,并阻止任何其他进程打开它。 要删除它,我们需要关闭该段。

关闭细分

打开一个共享内存段“附加”到它。 附加到该段之后,我们可以对其进行读取和写入,但是一旦完成操作,就必须与该段分离。 这是使用清单7中的shmop_close函数完成的。

这与处理文件时的fclose函数非常相似。 打开包含文件的流并对其进行读写后,我们必须将其关闭,否则将发生锁定。

清单7.使用shmop_close从段中分离
<?php

$shmid = shmop_open(864, 'c', 0755, 1024);
shmop_write($shmid, "Hello World!", 0);
shmop_delete($shmid);
shmop_close($shmid);

?>

使用共享内存作为存储选项

有了共享内存的基本知识以及对共享内存段的基本CRUD操作,现在该使这些知识发挥作用了。 我们可以将共享内存用作唯一的存储替代方案,从而提供诸如快速读/写操作和过程互操作性的好处。 对于Web应用程序,这意味着:

  • 缓存存储(数据库查询,Web服务数据,外部数据)
  • 会话存储
  • 应用程序之间的数据交换

在继续之前,我想介绍一个名为SimpleSHM的小型库。 SimpleSHM是用于使用PHP进行共享内存操作的小型抽象层,允许以面向对象的方式轻松操作段。 当编写使用共享内存进行存储的小型应用程序时,该库有助于创建更简洁的代码。 要开始使用SimpleSHM,请从GitHub页面获取一个压缩包。

您可以使用三种方法:读取,写入和删除。 简单地从类中实例化一个对象将控制共享内存段的打开。 清单8显示了基本用法。

清单8. SimpleSHM的基本用法
<?php

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

?>

请注意,没有为该类传递ID。 如果未传递ID,它将随机选择一个数字,然后使用该数字打开一个新细分。 我们可以传递一个数字作为构造函数的参数,以打开现有的段或使用特定的ID进行创建,如清单9所示。

清单9.打开一个特定的段
<?php

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

?>

魔术方法__destructor负责在段上调用shmop_close来取消设置对象以便与段分离。 我们将其称为“ SimpleSHM 101”。 现在,我们将其用于更高的目的:使用共享内存作为存储。 存储数据集需要序列化,因为数组或对象无法存储在内存中。 虽然此处使用JSON进行序列化,但是任何其他方法(例如XML或内置PHP序列化功能)都足够。 有关示例,请参见清单10。

清单10.使用共享内存作为存储
<?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应用程序中共享内存的功能。 有许多不同的方法可以巧妙地实现这种存储,唯一的限制是开发人员的创造力和技能。

结论

本文介绍了PHP工具箱中用于操纵共享内存段的大多数工具,并说明了共享内存的工作方式。 此外,它提供了有关改进Web应用程序的建议,并概述了在创建常见Web应用程序问题的解决方案时要考虑的一些因素。 概念和实施指南可以帮助您建立起点。 我们构建的早期模型可以帮助您设想更复杂的功能和解决方案。

下一步是什么?

我们概述了一些非常适合共享内存的常见问题,例如缓存,会话共享和应用程序之间的常见数据交换。 共享内存的简介为您提供了探索常见问题的更优雅解决方案的机会。 随意扩展SimpleSHM的当前实现,以满足您的需求,并将所做的更改归还给项目。


翻译自: https://www.ibm.com/developerworks/opensource/library/os-php-shared-memory/index.html

php共享内存

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值