swoole内存 memery 提供了很多种操作、有 table 、channel 、serialize mmap lock 等等,现在着重说说 table 、channel 都是做什么的:
memery 提供这么多种,适用场景是什么?
是做什么的?
内存操作的模块,在多进程编程中可以帮助开发者实现一些特殊的需求
所有模块均为多进程安全的,无需担心数据同步问题
Buffer
buffer 申请的内存并非共享内存,所以无法在多个进程间被共享。
Table
table中提供了 __construct 、column 、create、set、get、exist、count、del、incr、decr 这几种方法
incr 和 decr 这两个方法必须是整型或浮点类型
Table->column
内存表增加一列
bool Table->column(string $name, int $type, int $size = 0);
$name指定字段的名称
$type指定字段类型,支持3种类型,Table::TYPE_INT, Table::TYPE_FLOAT, Table::TYPE_STRING
$size指定字符串字段的最大长度,单位为字节。字符串类型的字段必须指定$size
类型
Table::TYPE_INT默认为4个字节,可以设置1,2,4,8一共4种长度
Table::TYPE_STRING设置后,设置的字符串不能超过此长度
Table::TYPE_FLOAT会占用8个字节的内存
整型溢出
由于Swoole底层使用有符号整型,如果传入的数值超过最大长度,可能会出现溢出。因此整数类型安全的值范围是:
1byte(int8):-127 ~ 127
2byte(int16):-32767 ~ 32767
4byte(int32):-2147483647 ~ 2147483647
8byte(int64):不会溢出
演示实例:
$table = new swoole_table(8); $table->column('data',$table::TYPE_STRING,1000); $table->column('id',$table::TYPE_INT,8); $table->create(); for($i=1;$i<120;$i++){ $table->set($i,['data'=>'data'.$i,'id'=>microtime(true)*10000]); } var_dump($table->get(1)); var_dump($table->get(2)); echo "table的数量".$table->count()."\n"; var_dump("判断数值字符串22是否存在".$table->exist('22')."\n"); var_dump("判断数值22是否存在".$table->exist(22)."\n"); var_dump("判断数值522是否存在".$table->exist('522')."\n"); /* foreach($table as $key=>$val){ echo $key."\n"; $table->del($key); } */ echo "table的数量".$table->count()."\n";
运行结果:
[root@localhost swoole]# php memerytable.php array(2) { ["data"]=> string(5) "data1" ["id"]=> int(864401274) } array(2) { ["data"]=> string(5) "data2" ["id"]=> int(864401275) } table的数量119 string(37) "判断数值字符串22是否存在1 " string(28) "判断数值22是否存在1 " string(28) "判断数值522是否存在 " table的数量119
问题:
1、foreach($table as $row){ $table->del($row['key']); } 请问这样能清空$table吗?
可以
2、遍历table执行table->del($key)之后table的空间会释放出来吗,还是说,只是删掉了数据,空间一直被占有,必须要重启服务才能释放table的空间?
答:table->del(key)会释放内存,但是如果程序运行后,不重启而且以后运行table时的key会改变时,
那么这个table就会因为新增加了不同的key而消耗内存,运行多了就会内存爆掉,综合来看,这个table很不安全(常驻内存运行而言),
除非每次运行的key都是一样的,否则一定会有爆内存的一天。
Channel
Swoole-1.9.0新增了一个新的内存数据结构Channel,用于实现高性能的进程间通信,底层基于共享内存+Mutex互斥锁实现,可实现用户态的高性能内存队列。
条件限制:
1、Channel可用于多进程环境下,底层在读取写入时会自动加锁,应用层不需要担心数据同步问题
2、必须在父进程内创建才可以在子进程内使用。
注意:
Channel
不受PHP
的memory_limit
控制
这是一个高性能的内存队列。
提供了 push pop 以及 stats 状态 这三个方法。
先进先出 没有提供其他的操作方式。
倘若验证队列长度,可使用 stats 中的 queue_num 得到
array(2) { ["queue_num"]=> int(2) ["queue_bytes"]=> int(32) }
php代码:
$chan=new swoole_channel(100); $n=2; $bytes=0; if(pcntl_fork()>0){ echo "father\n"; for($i=0;$i<$n;$i++){ $chan->push($i); } echo "total push success \n"; var_dump($chan->stats()); }else{ echo "Child \n"; for($i=0;$i<$n;$i++){ $data=$chan->pop(); print_r($data); echo "\n"; sleep(1); } echo "total pop success \n"; var_dump($chan->stats()); }
php运行实例:
[root@localhost swoole]# php memory_chanel.php father total push success array(2) { ["queue_num"]=> int(2) ["queue_bytes"]=> int(32) } Child 0 [root@localhost swoole]# 1 total pop success array(2) { ["queue_num"]=> int(0) ["queue_bytes"]=> int(0) }