BSD上的PHP后台进程使用100%的CPU

时间:2011-10-13 20:16:19

标签: php twitter freebsd background-process bsd

我有一个PHP脚本作为后台进程运行。这个脚本只是使用fopen来读取Twitter Streaming API。本质上是永远不会结束的http连接。不幸的是,我无法发布该剧本,因为它是专有的。 Ubuntu上的脚本运行正常,使用的CPU很少。但是在BSD上,脚本总是使用几乎100%的CPU。该脚本在两台机器上运行正常,并且是完全相同的脚本。任何人都可以想到一些可能指向正确方向的东西来解决这个问题吗?这是我编写的第一个在后台持续运行的PHP脚本。

脚本是一个无限循环,它每分钟读取数据并写入json文件。每当重新连接发生时,脚本都会写入MySQL数据库,这通常是在运行几天之后。该脚本没有别的,也不是很长。我没有使用BSD或编写运行无限循环的PHP脚本的经验。在此先感谢任何建议,如果这属于另一个StackExchange,请告诉我。我会尽快回答任何问题,因为我意识到这个问题非常模糊。

3 个答案:

答案 0 :(得分:1)

听起来我的一个功能就是在Linux上短暂阻止,但不是BSD。没有看到你的脚本很难具体,但我建议的一件事是在下一个循环迭代之前添加usleep()

usleep(100000); //Sleep for 100ms

你不需要长时间的睡眠......只需要你没有使用100%的CPU。

编辑:由于您提到您目前无法在后台运行此功能,我建议您查看this tutorial for "daemonizing" your script。包含了一些方便的代码来执行此操作。它甚至可以为init.d创建一个文件。

答案 1 :(得分:1)

如果没有看到脚本,很难给出明确的答案,但是您需要做的是确保您的脚本正在等待数据。您绝对应该做的就是在文件指针上调用stream_set_timeout($fp, 0);stream_set_blocking($fp, 0);

执行类似这样的应该避免竞赛的脚本的基本结构将是这样的:

// Open the file pointer and set blocking mode
$fp = fopen('http://www.domain.tld/somepage.file','r');
stream_set_timeout($fp, 1);
stream_set_blocking($fp, 1);

while (!feof($fp)) { // This should loop until the server closes the connection

  // This line should be pretty much the first line in the loop
  // It will try and fetch a line from $fp, and block for 1 second
  // or until one is available. This should help avoid racing
  // You can also use fread() in the same way if necessary
  if (($str = fgets($fp)) === FALSE) continue;

  // rest of app logic goes here

}

您可以使用sleep() / usleep()来避免竞争,但更好的方法是依靠阻止函数调用来阻止。如果它在一个操作系统上工作但在另一个操作系统上不工作,请尝试明确设置阻塞模式/行为,如上所述。

如果你无法通过调用fopen()传递HTTP URL来解决这个问题,那么PHP中的HTTP包装器实现可能会出现问题。要解决此问题,您可以使用fsockopen()并自行处理请求。这并不太难,特别是如果您只需要发送一个请求并读取一个恒定的流响应。

答案 2 :(得分:0)

代码看起来与实际读数有什么关系?你只是敲打插座直到你拿到东西吗?

处理这个问题的一个非常有效的方法是使用libevent extension,但这不适合虚弱的人。