PHP共享内存需用shmop_open()创建,配信号量防并发冲突;shmop仅支持字符串,sysvshm支持序列化变量;内存段需手动清理,否则残留内核中。

共享内存段的创建与基本读写
PHP 使用 shmop_open() 创建或打开一块共享内存区域,核心参数包括唯一键值(通常由 ftok() 生成)、访问标志、权限和大小。例如:
- "c" 表示“创建或打开”,适合多进程首次协作场景;
- 0644 是八进制权限,控制谁可读写;
- 1024 指定字节大小,必须足够容纳后续所有数据,且写入/读取时不能越界。
写入只能用字符串,需用 shmop_write() 明确指定偏移量;读取则通过 shmop_read() 指定起始位置和长度——若长度小于实际内容,结果会被截断。
用信号量避免并发写冲突
共享内存本身不带同步机制。多个 PHP 进程同时执行 shmop_write() 可能导致数据覆盖或错乱。此时需搭配系统信号量(如 sem_get()、sem_acquire()、sem_release())加锁:
- 每次修改前调用 sem_acquire() 获取独占权;
- 操作完成后立即 sem_release();
- 若未释放,其他进程会阻塞等待,直到超时或锁被释放。
注意:信号量 key 应与共享内存 key 独立生成(可用不同 ftok 文件标识符),避免混淆。
立即学习“PHP免费学习笔记(深入)”;
两种主流扩展的适用差异
shmop 和 sysvshm(含 shm_put_var/shm_get_var)都支持共享内存,但行为不同:
- shmop 更底层,只接受字符串,适合简单、高频、定长结构(如计数器、状态标记);
- sysvshm 支持混合类型(数组、对象序列化后存取),更易用,但单个变量有大小限制(默认约 64KB),且需确保 $shar_key 为整型;
- 两者均需手动清理:shmop_delete() 或 shm_remove() 标记删除,shmop_close() 或 shm_detach() 仅释放当前进程句柄。
跨进程生命周期与资源清理
共享内存段存在于系统内核中,不随某个 PHP 进程退出而自动销毁。因此必须主动管理:
- 建议在主进程统一调用 shmop_delete()(或 shm_remove())做逻辑删除;
- 所有子进程应在退出前调用 shmop_close()(或 shm_detach());
- 若某进程异常崩溃未关闭,其他进程仍可继续使用该段,但残留锁可能导致死锁——务必配合信号量超时设置或使用 pcntl_signal() 做兜底清理。
不复杂但容易忽略



















