You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何同浏览器下站点运行长时间脚本时无法打开其他页面?

为什么同一浏览器下同站点的第二个请求会被阻塞?

你遇到的这个问题确实和session直接相关,核心原因是PHP默认的session文件锁机制导致了请求阻塞,下面给你拆解清楚:

问题根源:PHP的session独占锁机制

当你的test.php脚本启动session(通常通过session_start())时,PHP会在服务器上创建或打开对应的session文件(默认存储在服务器的临时目录,比如/tmp),并且会给这个文件加上独占锁。这个锁的作用是保证session数据的一致性——防止多个请求同时读写同一个session数据,避免数据错乱。

但这个机制有个副作用:只要持有锁的脚本(也就是test.php)还在运行,所有使用同一个session ID的后续请求(比如你打开的index.php)都会被卡住,直到test.php执行完毕,PHP自动释放session文件锁,或者脚本主动调用session_write_close()释放锁。

为什么同一浏览器会触发这个问题?

同一浏览器访问同站点时,会自动携带相同的session ID Cookie。也就是说,你打开index.php的第二个标签页,会和test.php使用同一个session ID,所以它会尝试访问同一个session文件,而此时文件被test.php锁住了,只能等待锁释放。

为什么换浏览器就正常?

不同浏览器之间的Cookie是隔离的,新浏览器访问站点时会生成一个全新的session ID,对应服务器上另一个独立的session文件,自然不会和test.php的session文件锁产生冲突,所以能正常加载页面。

解决办法

针对这种长运行脚本的场景,你可以用这些方式避免阻塞:

  • 尽早释放session锁:如果test.php不需要全程操作session数据,在完成session读写后立刻调用session_write_close(),主动释放锁。比如:
    session_start();
    // 完成session的读写操作,比如存用户信息
    $_SESSION['user'] = 'xxx';
    // 立刻释放session锁
    session_write_close();
    
    // 后面的长时间运行逻辑就不会再阻塞其他请求了
    sleep(300); // 模拟5分钟的耗时操作
    
  • 改用非文件型session存储:比如将session存储在Redis、Memcached这类内存数据库中,它们的锁机制更轻量高效,不会像文件锁那样长时间阻塞请求。
  • 无session需求的页面不要启动session:如果index.php不需要用到session数据,就不要调用session_start(),这样它不会去尝试获取session锁,自然不会被阻塞。

内容的提问来源于stack exchange,提问作者Log

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:34:52