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
$chan->push($i);
}
echo "total push success \n";
var_dump($chan->stats());
}else{
echo "Child \n";
for($i=0;$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)
}