swoole多进程共享内存首选swoole\table,它基于共享内存+行锁实现高频安全读写;次选swoole\atomic用于无锁计数;复杂逻辑需swoole\lock加锁;shmop可手动管理但需自行同步;跨机或持久化场景用redis补充。

如果您在Swoole多进程环境中需要让不同Worker进程访问同一份内存数据,则必须绕过PHP原生的进程隔离限制。Swoole\Table 是专为此类场景设计的共享内存结构,它在底层映射至同一块系统共享内存区域,所有Worker进程均可直接读写。以下是2026年可用的、经验证有效的实现方式:
一、使用 Swoole\Table 创建共享内存表
Swoole\Table 是Swoole内置的高性能共享内存哈希表,支持字符串、整型、浮点型字段,具备行级锁和原子操作能力,适用于高频读写且结构固定的共享状态管理。
1、在 Server 启动前(如 onWorkerStart 或全局作用域)初始化 Table 实例,指定预估最大行数;
2、调用 column() 方法定义字段名、类型及长度,例如 name 字段为 TYPE_STRING 类型、长度64;
3、执行 create() 方法完成内存分配与结构注册;
4、在任意 Worker 进程中通过 set() 写入键值对,通过 get() 读取,所有进程看到的是同一份内存数据;
5、注意:Table 容量不可动态扩容,需在 create() 前准确预估容量,否则触发 Swoole\Table::ERR_TABLE_FULL 错误。
二、配合 Swoole\Atomic 实现无锁计数器同步
当仅需共享单一数值(如请求计数、在线人数)且要求高并发安全时,Swoole\Atomic 比 Table 更轻量,其底层基于 CPU 原子指令,无需加锁即可保证 incr/decr 操作的完整性。
1、在主进程或 onWorkerStart 中 new Swoole\Atomic(0) 初始化初始值;
2、各 Worker 进程调用 incr() 增加计数,返回操作后的新值;
3、调用 get() 获取当前值,该值对所有进程实时可见;
4、若需重置,调用 set() 赋新值;
5、注意:Atomic 仅支持 int64 类型,不支持字符串或浮点运算。
三、利用 Swoole\Lock 实现临界区互斥控制
当多个 Worker 需对同一 Table 行或外部资源(如文件、数据库连接)执行复合逻辑(读-改-写),必须引入显式锁机制防止竞态。Swoole\Lock 支持多种底层锁类型,推荐使用 FILE 或 PROCESS 类型以适配多进程环境。
1、在全局作用域 new Swoole\Lock(SWOOLE_LOCK_FILE, '/tmp/table_lock'); 创建跨进程锁;
2、在临界操作前调用 lock() 阻塞等待获取锁;
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
3、执行 Table 的 set()、get() 及其他业务逻辑;
4、操作完成后立即调用 unlock() 释放锁;
5、注意:未配对 unlock 可导致死锁,务必在 try-finally 或异常捕获结构中确保 unlock 执行。
四、通过 shmop 扩展手动管理共享内存段
对于需完全自控内存布局或兼容非Swoole环境的场景,可绕过 Table 封装,直接使用 PHP 内置 shmop 扩展操作系统共享内存。此方式灵活性高但需自行处理序列化、并发安全与内存释放。
1、调用 shmop_open() 创建或打开一个 key 对应的共享内存段;
2、使用 shmop_write() 写入序列化后的数据(如 json_encode);
3、在其他进程调用 shmop_read() 读取并反序列化;
4、操作完毕后,由任一进程调用 shmop_delete() 标记删除,并调用 shmop_close() 关闭句柄;
5、注意:shmop 不提供任何并发保护,必须配合 flock 或 Semaphore 扩展实现外部同步。
五、结合 Redis 作为 Table 的持久化/跨机补充方案
当共享数据需跨物理服务器、要求持久化或承载复杂结构(如嵌套数组、对象)时,Swoole\Table 不再适用,此时应选用 Redis 作为补充。虽有网络开销,但在2026年 Redis 7.x + Unix Domain Socket 模式下延迟已压至亚毫秒级。
1、启动 Redis 服务并启用 unixsocket /tmp/redis.sock 提升本地通信效率;
2、Worker 进程使用 Swoole\Coroutine\Redis 或 predis 异步客户端连接;
3、对高频简单键值使用 SET/GET,对计数使用 INCR/DECR,对集合使用 HSET/HGETALL;
4、设置合理超时(如 setOption(Redis::OPT_READ_TIMEOUT, 0.01))避免阻塞协程;
5、注意:Redis 是独立进程,不共享 PHP 内存,所有数据均经序列化传输。










