2016-07-05 110 views
1

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

+1

我不是一个判断,但共享主机和90秒的file_get_contents执行时间。这是过度使用的秘诀,禁止您的托管(违反公平使用政策)。我建议你调查排队请求并通过CRON在一天中均匀处理这些请求。 –

+0

@JamieBicknell我同意,但是如果使用共享主机,CRON肯定不可用,所以自定义任务队列是必需的。 – Jocelyn

+0

我还没有遇到任何不允许CRON的信誉良好的共享主机。然而,他们会有限制,例如每10或15分钟运行一次,最大执行时间为60秒,但体面的共享主机将拥有CRON。 –

回答

1

那么有多种方式可以并行运行任务,如果这就是你想要实现的目标,但要牢记PHP是一种高级脚本语言,并且它的最初目的是为无状态的HTTP请求提供服务。

这里有扩展名,例如Gearman,这个扩展允许应用程序并行完成任务。

显然这将是你的风向标,因为你可能只使用服务来托管。得到像vps一样,从OVH的vps比大多数网络托管服务便宜。

+0

你的意思是vps,而不是vpn? – user897234

+0

是的抱歉,我的意思是虚拟专用服务器 –

1

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

你必须玩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); 
} 
+0

有没有在代码中限制叉的数量的方法,例如,如果传递200个链接的数组,这是200个同时运行的'file_get_contents'试图并行工作,这将抓取....'$ max'似乎没有被使用。 – Martin

+0

@Martin是的,这里是现在的限制,它是'$ max'),它用于:while($ child> = $ max){'。在这个例子中,我们有3个线程。 –

+0

@Martin np!)感谢您的关注! –