php多进程 共享内存,多进程共享数据

# 多进程共享数据

[TOC]

由于`PHP`语言不支持多线程,因此`Swoole`使用多进程模式。在多进程模式下存在进程内存隔离,在工作进程内修改`global`全局变量和超全局变量时,在其他进程是无效的。

> 设置`worker_num=1`时,不存在进程隔离,可以使用全局变量保存数据

## 进程隔离

~~~

$fds = array();

$server->on('connect', function ($server, $fd){

echo "connection open: {$fd}\n";

global $fds;

$fds[] = $fd;

var_dump($fds);

});

~~~

`$fds`虽然是全局变量,但只在当前的进程内有效。`Swoole`服务器底层会创建多个`Worker`进程,在`var_dump($fds)`打印出来的值,只有部分连接的`fd`。

对应的解决方案就是使用外部存储服务:

* 数据库,如:`MySQL`、`MongoDB`

* 缓存服务器,如:`Redis`、`Memcache`

* 磁盘文件,多进程并发读写时需要加锁

普通的数据库和磁盘文件操作,存在较多`IO`等待时间。因此推荐使用:

* `Redis`内存数据库,读写速度非常快

* `/dev/shm`内存文件系统,读写操作全部在内存中完成,无`IO`消耗,性能极高

除了使用存储之外,还可以使用共享内存来保存数据

## 共享内存

`PHP`提供了多套共享内存的扩展,但实际上真正在实际项目中可用的并不多。

#### shm 扩展

提供了`shm_put_var`/`shm_get_var`共享内存读写方法。但其底层实现使用链表结构,在保存大量数值时时间复杂度为`O(N)`,性能非常差。并且读写数据没有加锁,存在数据同步问题,需要使用者自行加锁。

> 不推荐使用

#### shmop 扩展

提供了`shmop_read`/`shmop_write`共享内存读写方法。仅提供了基础的共享内存操作指令,并未提供数据结构和封装。不适合普通开发者使用。

> 不推荐使用

#### apcu 扩展

提供了`apc_fetch`/`apc_store`可以使用`Key-Value`方式访问。`APC`扩展总体上是可以用于实际项目的,缺点是锁的粒度较粗,在大量并发读写操作时锁的碰撞较为密集。

> `yac`扩展,不适合用于保存数据,其设计原理导致存在一定的数据`miss`率,仅作为缓存,不可作为存储

#### Swoole\\Table

`Swoole`官方提供的共享内存读写工具,提供了`Key-Value`操作方式,使用非常简单。底层使用自旋锁实现,在大量并发读写操作时性能依然非常强劲。推荐使用。`Table`仍然存在两个缺点,使用时需要根据实际情况来选择。

* 提前申请内存,`Table`在使用前就需要分配好内存,可能会占用较多内存

* 无法动态扩容,`Table`内存管理是静态的,不支持动态申请新内存,因此一个`Table`在设置好行数并创建之后,使用时不能超过限制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值