作为程序员一定要保持良好的睡眠,才能好编程

Swoole内存相关操作

发布时间:2019-03-26

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不受PHPmemory_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)
}