【问题标题】:PHP: Can only a single instance of a particular script be executed at once?PHP:一次只能执行特定脚本的单个实例吗?
【发布时间】:2016-02-04 05:52:30
【问题描述】:

我有一个简单的小脚本,打印当前时间,休眠十秒,然后再次打印当前时间:

<?php
echo "<html><head><title>title</title></head><body>";
echo "<p>Pre-sleep: " . date("H:i:s") . "</p>";
sleep(10);
echo "<p>Post-sleep: " . date("H:i:s") . "</p>";
echo "</body></html>";
?>

我实际上在两个不同的页面中有完全相同的代码(比如“blah1.php”和“blah2.php”)。如果我使用两个不同的浏览器(基本上)同时访问这两个不同的页面,这两个页面似乎(基本上)同时运行:

blah1.php 输出:

睡前:11:15:26

睡眠后:11:15:36

blah2.php 输出:

睡前:11:15:27

睡眠后:11:15:37

但如果我改为使用两种不同的浏览器来点击 same 脚本的副本,就好像第二个实例甚至在第一个实例完成之前开始执行:

blah1.php 实例 1 输出

睡前:11:09:07

睡眠后:11:09:17

blah1.php 实例 2 输出

睡前:11:09:17

睡眠后:11:09:27

所以看起来 PHP —— 或者至少我的特定 PHP 以它当前配置的方式配置—— 将排队任何特定脚本的请求,尽管能够同时为单独的脚本提供请求?我是不是误会了?

这是预期的吗?这是普遍现象吗?或者它可能与 sleep() 函数或实际运行 PHP 脚本的特定服务器(在我的例子中是 Apache)或操作系统或类似的东西有关?

我可以依赖这种行为(对特定页面的请求排队并且从不同时执行)吗?另一方面,我可以阻止这种行为吗?

提前致谢。

更新:我现在认为该问题与 PHP、Apache 或服务器端的任何东西无关。

我突然意识到,当我说“两个不同的浏览器”时,这实际上是不准确的:我实际上是从 Firefox 的两个不同的窗口(在同一台计算机上)发出请求的。因此,我尝试使用一个 Firefox 和一个 IE,它们同时在服务器端运行。

然后我再次尝试使用两个不同的 Firefox 窗口,并查看了网络嗅探器。在第一个窗口的响应完成之前,第二个窗口甚至没有发送 GET 请求。

所以看起来这种行为在 Firefox 上:至少在某些情况下,如果您尝试从 Firefox 向同一个 URL 发出两个请求,Firefox 会将它们排队而不是同时处理它们。

【问题讨论】:

  • Web 服务器可能会排队请求,但 PHP 不会。 PHP 启动多个服务来同时处理每个请求,直到请求过多。
  • 在 Web 服务器执行的脚本中使用 sleep 不是一个好主意。编写脚本以尽快将页面移出大门。
  • Ed Heal,谢谢,但我并不打算将 sleep 用于任何真正的目的。我只是在写一些实验代码,试图弄清楚如何正确使用 MySQL 的 GET_LOCK 函数。它的行为方式让我感到惊讶,进一步的调查似乎揭示了原因是因为某些东西正在排队对任何单个 PHP 页面的请求,因此在任何给定时间只有一个会执行。 sleep 函数只是在问题中证明这一点的一种简单方法。

标签: php apache


【解决方案1】:

您可以执行任意数量的 PHP 脚本实例。 当您通过浏览器访问脚本时,您正在通过 Web 服务器访问它。当您通过 Web 服务器访问脚本时,所发生的一切就是服务器执行了 1 个脚本实例。

从上面看,您的网络服务器似乎设置为对具有上述副作用的传入请求进行排队。

【讨论】:

    【解决方案2】:

    如果需要访问同一个PHP实例所以需要使用线程:example

    ...但这对于仅仅测试 MySQL 的 GET_LOCK 来说可能太复杂了。

    另一方面,你的结果可能是因为第一次调用阻塞了锁名。

    GET_LOCK(str,timeout)

    尝试使用由字符串 str 给出的名称获取锁,使用 timeout 秒的超时。负超时值意味着无限超时。锁是独占的。由一个会话持有时,其他会话无法获得同名锁。

    如果锁定成功返回1,如果尝试超时返回0(例如,因为另一个客户端之前锁定了名称),或者如果发生错误(例如用完)返回NULL内存或线程被 mysqladmin kill 杀死)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      相关资源
      最近更新 更多