Cron作业可以用来用PHP模拟多线程吗?

Cron作业可以用来用PHP模拟多线程吗?,php,multithreading,cron,Php,Multithreading,Cron,我有一个mysql数据库表,里面有1000多条记录,比如说5000条记录。每条记录都有一个processed布尔标志,默认为false(0)。我想做的是每分钟在cron上运行一个PHP脚本。其代码如下所示: <?php process(); function process() { $sql = "SELECT id FROM items WHERE processed = '0' ORDER BY id ASC LIMIT 1"; $result = $this->d

我有一个mysql数据库表,里面有1000多条记录,比如说5000条记录。每条记录都有一个
processed
布尔标志,默认为
false(0)
。我想做的是每分钟在cron上运行一个PHP脚本。其代码如下所示:

<?php
process();

function process()
{
   $sql = "SELECT id FROM items WHERE processed = '0' ORDER BY id ASC LIMIT 1";
   $result = $this->db->query($sql);

   if (! $result->has_rows())
     die;

   $id = $result->getSingle('id');
   processItem($id); //Will set processed to 1 after processing is done
   process();
}
?>

我有几件事要说:

首先,您使用递归来处理多行。如果递归太深,这可能会导致问题。而是使用一个简单的循环

其次,您知道这段代码是否可以从多次运行中获益吗?如果机器是CPU绑定的,它可能不会从另一个线程中受益。我建议您手动检查有多少线程工作得最好。更多的线程并不总是让事情进展得更快,在某些情况下,实际上会减慢一切

最后,我肯定会限制这些脚本中有多少可以并发运行。这可以通过确保每个脚本的运行时间不超过5分钟来实现。或者,您可以保留活动脚本的数量,并确保它不会超过您在我的第二个建议中确定的最大数量

编辑:我已经添加了有关递归可能导致的问题的更多信息: 每次递归调用函数时,堆栈上的额外空间都会被用完。该空间存储任何局部变量以及函数的地址(允许它在被调用函数退出时恢复状态)。堆栈只有有限的空间,因此最终您的程序将因堆栈溢出而崩溃。尝试运行以下简单程序:

function a($i) { 
   print $i . "\n"; 
   a($i + 1);
}
a(0);

在我的系统上,它在608739次迭代后崩溃了PHP。在更复杂的函数中,这个数字可能要小得多。一个简单的循环没有这些开销,因此它没有这个问题。

递归似乎根本没有必要,正如bramp所说,可能会导致问题。为什么不

$sql = "SELECT id FROM items WHERE processed = '0' ORDER BY id ASC LIMIT 1";

while ( ($result = $this->db->query($sql) && $result->has_rows() ) {
   processItem( $result->getSingle('id') );
}

然而我预见到了更大的问题。如果您打算每分钟运行一次此脚本,您有什么机制来停止执行以前执行的脚本,这些脚本可能仍在运行?您可能会多次处理同一ID

如果您绝对需要(伪)多线程方法,我建议如下:

  • 获取一系列或所有未处理的ID,而不是一次只获取一个
  • 使用
    curl\u multi\u
    函数族,将上述结果的子集(组
    n
    id)传递给另一个脚本以执行实际处理

  • 此方法允许您更好地控制整个过程,并防止不必要的单个查询来获取未处理的ID。

    我启动了一个项目来解决完全相同的问题。它可以连续运行一个脚本,并在需求较高时并行运行更多实例。如果无需执行任何操作,则它将在运行脚本实例之前等待指定的时间间隔


    如果您感兴趣,请通读一些用例:

    实际上,上面的代码似乎对
    限制0没有任何作用,谢谢您的回答。递归会导致什么问题?我已经在主要答案正文中回答了你关于递归会导致什么问题的问题。谢谢你,伙计,特别是关于检查脚本是否已经运行了5分钟并终止脚本的提示。感谢您的帮助:)