PHP 避免无限 while 循环进行连续处理

问题描述 投票:0回答:5

我需要一个在 php 中自行执行的函数,无需 crone 的帮助。我想出了以下对我来说很有效的代码,但由于它是一个永无止境的循环,它会对我的服务器或脚本造成任何问题,如果是的话,请给我一些建议或替代方案。谢谢。

$interval=60; //minutes
set_time_limit(0);

while (1){
    $now=time();
    #do the routine job, trigger a php function and what not.
    sleep($interval*60-(time()-$now));
}
php loops
5个回答
14
投票

我们在实时系统环境中使用了无限循环,基本上是等待传入的短信,然后对其进行处理。我们发现这样做会随着时间的推移而占用服务器资源,并且必须重新启动服务器才能释放内存。

我们遇到的另一个问题是,当您在浏览器中执行无限循环的脚本时,即使您点击停止按钮,它也会继续运行,除非您重新启动 Apache。

    while (1){ //infinite loop
    // write code to insert text to a file
    // The file size will still continue to grow 
    //even when you click 'stop' in your browser.
    }

解决方案是在命令行上将 PHP 脚本作为守护进程运行。方法如下:

nohup php myscript.php &

&
将您的进程置于后台。

我们不仅发现此方法占用内存较少,而且您还可以通过运行以下命令来终止它而无需重新启动 apache :

kill processid

编辑:正如 Dagon 指出的那样,这并不是将 PHP 作为“守护进程”运行的真正方法,但使用

nohup
命令可以被视为穷人将进程作为守护进程运行的方式。


2
投票

您可以使用 time_sleep_until() 函数。它将返回 TRUE OR FALSE

$interval=60; //minutes
  set_time_limit( 0 );
  $sleep = $interval*60-(time());

  while ( 1 ){
     if(time() != $sleep) {
       // the looping will pause on the specific time it was set to sleep
       // it will loop again once it finish sleeping.
       time_sleep_until($sleep); 
     }
     #do the routine job, trigger a php function and what not.
   }

2
投票

在 php 中创建守护进程的方法有很多种,并且已经存在很长时间了。

仅仅在后台运行某些东西是不好的。例如,如果它尝试打印某些内容并且控制台关闭,则程序将终止。

我在 Linux 上使用的一种方法是 php-cli 脚本中的 pcntl_fork(),它基本上将脚本分成两个 PID。让父进程杀死自己,并让子进程再次分叉自己。再次让父进程自行终止。子进程现在将完全分离,可以愉快地在后台做任何你想做的事情。

$i = 0;
do{
    $pid = pcntl_fork();
    if( $pid == -1 ){
        die( "Could not fork, exiting.\n" );
    }else if ( $pid != 0 ){
        // We are the parent
        die( "Level $i forking worked, exiting.\n" );
    }else{
        // We are the child.
        ++$i;
    }
}while( $i < 2 );

// This is the daemon child, do your thing here.

不幸的是,如果该模型崩溃或服务器重新启动,则无法自行重新启动。 (这个可以通过创意解决,但是……)

要获得重生的稳健性,请尝试使用 Upstart 脚本(如果您使用的是 Ubuntu。)这是一个教程 - 但我还没有尝试过此方法。


1
投票

while(1)
表示无限循环。如果你想打破它,你应该根据条件使用
break
。 例如,.

while (1){ //infinite loop
    $now=time();
    #do the routine job, trigger a php function and what no.
    sleep($interval*60-(time()-$now));
    if(condition) break; //it will break when condition is true
}

0
投票

做这个

while (1==1){ echo an infinite loop }

© www.soinside.com 2019 - 2024. All rights reserved.