php-semaphore 不能通过 composer 安装,它只是 ext-sysvsem 的封装,必须通过系统包管理器安装并启用 php 扩展;windows 不支持,web 应用应改用 laravel-semaphore 等基于 redis 的分布式锁方案。

Composer 安装 php-semaphore 会失败,别试了
php-semaphore 是 PHP 的 sysvsem 扩展封装,不是 Composer 包——它没有 composer.json,不能通过 composer require 安装。你搜到的所谓 “php-semaphore” GitHub 仓库,基本是过时的、无人维护的 wrapper,或直接指向系统扩展本身。
真正能用的只有两件事:ext-sysvsem(Linux/Unix 系统扩展)和 ext-sockets(部分替代方案),二者都必须编译进 PHP,无法靠 Composer 加载。
- 运行
php -m | grep sysv,若无输出,说明扩展未启用 - Debian/Ubuntu 下安装命令是
sudo apt install php-sysvsem,之后需在php.ini中确认extension=sysvsem已取消注释 - macOS(Homebrew)需重新编译 PHP:比如
brew install php@8.3 --with-sysvsem - Windows 完全不支持
sysvsem,文档明确写着 “neither semaphores nor inter-process messaging functions are supported on that platform”
为什么你不该在 Web 应用里用 sysvsem
即使你成功启用了 ext-sysvsem,它也不适合 Laravel、Symfony 或任何现代 PHP Web 框架的并发控制场景。
根本原因有三个:
-
sem_get()创建的信号量是系统级 IPC 资源,生命周期独立于 PHP 进程;但 Apache/FPM worker 崩溃或超时后,信号量可能残留,导致后续请求永久阻塞(EAGAIN或死锁) - 没有自动过期机制,
sem_remove()必须显式调用,而异常、超时、kill -9 都会让这一步丢失 - 它只在单机有效,无法用于容器化部署、K8s 多副本或 Redis/Memcached 分布式缓存环境
换句话说:它能 work,但不可靠;能跑通 demo,但扛不住线上流量。
laravel-semaphore 才是你该用的“信号量”
名字带 “semaphore”,但它底层用的是 Cache::store('redis')->lock() 或 Memcached::add(),本质是分布式锁 + TTL 自动释放,这才是生产环境唯一可行路径。
关键配置点只有两个:
- 确保
config/cache.php中'default' => 'redis',且 Redis 连接健康(别被队列或 session 抢光连接) - 调用时必须包裹全部可能出错的逻辑,例如:
Semaphore::attempt('inventory_update', 30, function () { $stock = Stock::lockForUpdate()->find(1); if ($stock->quantity > 0) { $stock->decrement('quantity'); return true; } throw new \Exception('Out of stock'); });漏掉任何分支(比如 catch 块里没 re-throw、或 finally 里没 unlock),都会让锁滞留
如果非要用原生 sysvsem,只限 CLI 场景
仅当你写的是长期运行的 PHP CLI 脚本(如守护进程、批处理任务),且确定只部署在一台物理机上,才考虑 sem_get/sem_acquire。
务必遵守这三条铁律:
- 每次
sem_get()后立即检查返回值是否为false,并用error_get_last()判断是否因 key 冲突失败 - 所有
sem_acquire()必须配对sem_release(),且放在try/finally块中,不能依赖__destruct - 设置合理
$max_acquire(第三个参数),避免无限等待;超时后应usleep()退避再试,而非重试sem_acquire
跨进程信号量真正的难点从来不在“怎么加锁”,而在于“锁失效了谁来清理”。系统 V IPC 不提供原子性兜底,这个责任最终得由你自己代码承担。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











