【问题标题】:Don't wait for file_get_contents() to finish不要等待 file_get_contents() 完成
【发布时间】:2016-07-05 13:36:06
【问题描述】:

有没有办法在不等待第一个完成的情况下调用多个file_get_contents。我有一些 PHP 脚本会做一些繁重的工作,其中一个脚本的执行时间超过 1.5 分钟,所以我想同时调用它们以减少执行时间。目前我有多个 file_get_contents 但要运行下一个 file_get_contents 第一个需要先完成。我尝试了exec 方法,但它在服务器上被阻止(共享主机)。

【问题讨论】:

  • 我不是判断的,而是共享主机和 90 秒的 file_get_contents 执行时间。这是过度使用和禁止托管的秘诀(违反公平使用政策)。我建议您调查排队请求并通过 CRON 全天均匀处理这些请求。
  • @JamieBicknell 我同意,但是如果使用共享主机,CRON 肯定不可用,因此需要自定义任务队列。
  • 我没有遇到任何不允许 CRON 的信誉良好的共享主机。然而,它们会受到限制,例如最小运行时间为每 10 或 15 分钟一次,最大执行时间为 60 秒,但一个体面的共享主机将具有 CRON。

标签: php multithreading performance


【解决方案1】:

如果这是您想要实现的目标,那么有一些并行运行任务的方法,但请记住 PHP 是一种高级脚本语言,它的最初目的是为无状态 HTTP 请求提供服务。

有像Gearman 这样的扩展,这个扩展允许应用程序并行完成任务。

显然,这对您来说是风向标,因为您可能正在使用仅用于托管的服务。获得类似 vps 的东西,OVH 的 vps 比大多数网络托管服务便宜。

【讨论】:

  • 你是说vps,不是vpn?
  • 是的,对不起,我的意思是虚拟专用服务器
【解决方案2】:

是的,这是可能的!但这有点棘手!

你必须和forks一起玩。
我同意队列和其他......但只是为了能力,这里是一个例子:

<?php

declare(ticks = 1);

$a = [
    'https://twitter.com',
    'https://facebook.com',
    'https://stackoverflow.com',
    'https://linkedin.com',
    'https://github.com',
];

// Count of php threads (forks or processes).
$max = 3;
// Child counter.
$child = 0;

pcntl_signal(SIGCHLD, function ($signo) {
    global $child;
    if ($signo === SIGCLD) {
        while (($pid = pcntl_wait($signo, WNOHANG)) > 0) {
            $signal = pcntl_wexitstatus($signo);
            $child--;
        }
    }
});

foreach ($a as $item) {
    while ($child >= $max) {
        sleep(1);
    }
    $child++;
    $pid = pcntl_fork();
    if ($pid) {
    } else {
        // Child fork.
        sleep(1);
        // HERE YOUR CODE:
        echo file_get_contents($item);
        exit(0);
    }
}

while ($child != 0) {
    sleep(1);
}

【讨论】:

  • 代码中有没有办法限制分叉的数量,例如,如果传递了一个包含 200 个链接的数组,那就是 200 个同时 file_get_contents 试图并行工作,那就会爬.. .. $max 似乎没有被使用。
  • @Martin 是的,这里有限制,它是$max) 使用:while ($child &gt;= $max) {。在这个例子中,我们有 3 个线程。
  • @Martin np!)感谢您的关注!
  • 您的while 所做的只是等待一秒钟再继续,因此似乎不会限制分叉的执行次数(仍然有 200 个调用,只是分布在 196 个秒)。如果每个 file_get_contents 调用需要 1.25 秒才能完成,那么这仍然会导致系统耗尽
  • @Martin 也可以在htopps aux|grep thisScriptName 中观察实际进程的数量...
猜你喜欢
  • 1970-01-01
  • 2014-06-27
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
相关资源
最近更新 更多