php 在后台线程/进程中调用函数(分叉)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9014062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:59:25  来源:igfitidea点击:

Calling a function in a background thread / process (forking)

phpparallel-processingfork

提问by xbonez

I have code that's somewhat like this:

我的代码有点像这样:

($i=0; $i < 100; $i++)
{
   do ($foo[$i]);
}

The above is a time intensive task, and I was hoping to be able to create a function, and call it twice like below

以上是一项耗时的任务,我希望能够创建一个函数,并像下面这样调用它两次

function wrapper($start;$end)
{
    ($i=$start; $i < $end; $i++)
    {
       do ($foo[$i]);
    }
}
//have both of these run in parallel
wrapper(0,50);
wrapper(51,100);

I looked at Gearman but I cannot use it as I cannot install the gearman server (since I'm on a shared server). It seems like the way to achieve this would be by forking. I tried reading up a lot about it, but documentation and support is scant. Any help / wireframe code would be appreciated.

我查看了 Gearman,但我无法使用它,因为我无法安装 gearman 服务器(因为我在共享服务器上)。似乎实现这一目标的方法是分叉。我试着阅读了很多关于它的信息,但文档和支持很少。任何帮助/线框代码将不胜感激。

To define my question, how could I call wrapper()passing in arguments such that it executes in a child process. Also, its important that I be able to register a callback function.

为了定义我的问题,我如何调用wrapper()传入参数以便它在子进程中执行。此外,重要的是我能够注册回调函数。

Additional Details: PHP 5.3, running on Linux server. Script is executed by cgi-fcgi.

附加细节:PHP 5.3,在 Linux 服务器上运行。脚本由 cgi-fcgi 执行。

I think this is how I am supposed to spawn a child process, but how can I use it to spawn multiple child processes? And how do I register a callback function?

我认为这就是我应该如何生成子进程,但是如何使用它来生成多个子进程?以及如何注册回调函数?

$pid = pcntl_fork(); 

if ( $pid == -1 ) {        
    // Fork failed            
    exit(1); 
} else if ( $pid ) { 
    // The parent process
    //should I repeat this same code here to spawn another child process?

} else { 
    // the child process 
    //can I call wrapper from here and will it run in this child process?

采纳答案by Beel

From "Tudor Barbu's professional blog"
(http://blog.motane.lu/2009/01/02/multithreading-in-php/)

来自“Tudor Barbu的专业博客”
http://blog.motane.lu/2009/01/02/multithreading-in-php/

require_once( 'Thread.php' );

// test to see if threading is available
if( ! Thread::isAvailable() ) {
    die( 'Threads not supported' );
}

// function to be ran on separate threads
function paralel( $_limit, $_name ) {
    for ( $index = 0; $index < $_limit; $index++ ) {
        echo 'Now running thread ' . $_name . PHP_EOL;
        sleep( 1 );
    }
}

// create 2 thread objects
$t1 = new Thread( 'paralel' );
$t2 = new Thread( 'paralel' );

// start them
$t1->start( 10, 't1' );
$t2->start( 10, 't2' );

// keep the program running until the threads finish
while( $t1->isAlive() && $t2->isAlive() ) {

}

Download Thread.php

下载线程.php

回答by 0xen

If you are using Linux you can take advantage of the command line and do

如果您使用的是 Linux,则可以利用命令行并执行

public function newWrapperInstance($start,$end){
    exec('bash -c "exec nohup setsid php-cli yourFile.php '.$start.' '.$end.' > /dev/null 2>&1 &"');
}

This will create a new instance of PHP in the background and detach itself from the exec function in the primary thread.

这将在后台创建一个新的 PHP 实例,并将自身与主线程中的 exec 函数分离。

Warning: The only downside is you can't control what those threads do once they are created.

警告:唯一的缺点是您无法控制这些线程创建后的操作。