【问题标题】:Serve one client at a time一次服务一位客户
【发布时间】:2012-11-22 12:49:07
【问题描述】:

我需要编写一个每次只能处理一个请求的 php 脚本。也就是说,如果用户请求该页面,则必须在未完全处理之前的请求之前为他提供服务。

为了实现这一点,我会使用应用程序变量,但如果我很好理解的话,我发现 php 没有类似的东西。

然后我尝试使用apc,将这段代码放在一起:

<?php

  while (apc_fetch('foo')) {
    echo "waiting...\n";
    sleep(1);
  }

  $foo = true;
  apc_store('foo', $foo);

  echo "results.";
  sleep(10);

  apc_delete('foo');

?>

但是如果我打开这个页面两次,我看到的只是results.。我也期待阅读一些waiting...,因为当我第二次加载页面时,第一次应该将foo 设置为true

这是对apc 的合法(但错误)使用吗?我是不是用错了工具?

【问题讨论】:

  • 这不是 apache 的标准行为(一次服务一个用户请求)(使用一个处理器时)?不管怎样,为什么不使用flock() 或PHP 会话变量? (无法回答 apc,抱歉)
  • 你在这里完全错误的道路,你所描述的永远不会奏效。假设您有正在执行的请求 1 并且请求 2 已排队 - 请求 2 不会说“等待”,它会挂起浏览器,直到服务器执行请求 2 的代码。这就是你可以去的地方,您可以延迟执行,或者您可以简单地选择不执行任何工作代码并通知您的客户端#2此时无法完成请求。这里没有“实时更新”。
  • 正确的做法是使用信号量。一个快速的谷歌告诉我 PHP 支持它们。
  • @N.B.不完全的。您可以向浏览器抛出大量数据(例如&lt;!-- tick --&gt;)并刷新。至少 Firefox 会显示“等待...”。它很丑,不应该在生产服务器上使用,但它可以工作。
  • 如果我必须实现这样的事情,我会使用 Ajax 来动态更新我的页面和某种面向数据库的信号量或队列。

标签: php


【解决方案1】:
<?php

  while ($var = apc_fetch('foo')) {
    echo "apc_fetch positive, got ".var_export( $var, true)."\n";
    sleep(1);
  }
  echo "apc_fetch was negative, continuing. \n";

  $foo = "asd";
  apc_store('foo', $foo);
  if( !apc_fetch('foo')) {
     echo "Btw, apc_store was not successful with foo\n";
  }

  echo date('c').": results.";
  flush();
  sleep(10);

  apc_delete('foo');

?>

【讨论】:

    【解决方案2】:

    我不喜欢回答自己的问题,但最后这是我发现做我想做的最简单的方法:

    <?php
    
    $fp = fopen("lock.txt", "r");
    
    if (flock($fp, LOCK_EX)) {  // acquire
    
      echo "processing...";
    
      //if (isset($_GET['sleep'])) sleep(5); // decomment this line to test:
                                             // load "script.php?sleep=1" and then
                                             // load "script.php". The second page will
                                             // wait until the first one ends.
    
      flock($fp, LOCK_UN); // release
    
    } else {
      // exception handling
      echo "ERROR: unable to flock()";
    }
    
    fclose($fp);
    
    ?>
    

    【讨论】:

      【解决方案3】:

      您的 apc 设置是否正确? apc_fetch 出错时返回 false。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-26
        • 2017-08-29
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多