PHP中连续调用sleep()总耗时为各参数之和,因单线程同步执行,不存在覆盖或并发;usleep()单位为微秒,time_nanosleep()为秒+纳秒;信号中断和SAPI超时更易导致线上异常。

PHP中连续调用sleep()是累加的,不是覆盖或并发
多个sleep()按顺序执行,总耗时等于各参数之和。PHP是单线程同步执行的,不存在“叠加延时”这种并发概念——它只是老老实实一个接一个地等。
常见误解是以为第二次sleep(2)会“覆盖”第一次的sleep(3),实际完全不会。只要没被中断(如信号、超时),每个sleep()都独立完成。
-
sleep(3); sleep(2);→ 总耗时约5秒(忽略函数调用开销) - 中间插了
echo或数据库查询?不影响sleep()计时,它们各自算各自的 - 如果脚本设置了
max_execution_time,总延时超过该值会直接Fatal error: Maximum execution time exceeded
用usleep()和time_nanosleep()要注意精度和单位
毫秒级以下延时不能靠sleep()(最小单位是秒),得换函数。但单位容易搞错,而且行为有差异:
-
usleep(1500000)→ 睡1.5秒(参数单位是微秒) -
time_nanosleep(1, 500000000)→ 睡1秒500毫秒(参数是sec+nano sec) -
usleep()在Windows上可能不精确,某些旧版本甚至只支持到10ms粒度 -
time_nanosleep()在部分Linux系统上可能被信号中断,返回false并设置$errno,需手动重试
循环里反复sleep()容易触发超时或被SAPI截断
Web环境(如Apache、FPM)对单次请求有硬性时间限制,连续延时极易撞墙。比如:
立即学习“PHP免费学习笔记(深入)”;
for ($i = 0; $i < 10; $i++) {
sleep(3); // 每次3秒,10次就是30秒
}这段代码在默认max_execution_time=30的配置下,大概率在第10次前就报错。更麻烦的是:Nginx等反向代理还有proxy_read_timeout,它不管PHP内部怎么睡,只看从响应头发出到结束的时间。
- CLI模式相对自由,但也要留意
set_time_limit(0)是否生效(有些SAPI禁用该函数) - 想“分段延时”,别用循环+
sleep(),改用异步任务队列或定时器回调 - 调试时加
echo microtime(true)."\n";可验证每次sleep()是否真按预期挂起
信号中断会让sleep()提前返回,且不抛异常
Unix-like系统下,若进程收到SIGALRM、SIGHUP等信号,sleep()可能提前退出,返回剩余秒数(非0),而不是继续等到原定时间。
-
var_dump(sleep(5));→ 若2秒后被信号中断,输出int(3) - 这意味着你以为睡了5秒,其实只睡了2秒,后续逻辑可能错乱
- 健壮写法是检查返回值:
while (sleep(5) > 0) { /* 重试 */ } -
pcntl_signal()注册处理器后,务必调用pcntl_signal_dispatch(),否则信号可能延迟处理,影响sleep()行为
实际跑起来才发现,信号中断和SAPI超时这两点,比“怎么叠加”本身更常导致线上行为不符预期。











