PHP+fork():如何在PHP代码中运行fork


PHP+fork(): How to run a fork in a PHP code

我正在CodeIgniter-Ubuntu服务器上运行我的代码。

我一直在研究异步方式来运行函数。

这是我的功能:

<?php   
    // Registers a new keyword for prod to the DB. 
    public function add_keyword() {
        $keyword_p = $this->input->post('key_word');
        $prod      = $this->input->post('prod_name');
        $prod      = $this->kas_model->search_prod_name($prod);
        $prod      = $prod[0]->prod_id;
        $country   = $this->input->post('key_country');
        $keyword = explode(", ", $keyword_p);
        var_dump($keyword); 
        $keyword_count = count($keyword);
        echo "the keyword count: $keyword_count";
        // problematic part that needs forking
        for ($i=0; $i < $keyword_count ; $i++) { 
            // get new vars from $keyword_count
            // run API functions to get new data_arrays
            // inserts new data for each $keyword_count to the DB 
        }
        // Redirect to main page. 
        redirect('banana/kas'); 
    }

"foreach"使用具有慢速API的变量,并更新数据库。

我看过一些使用fork的教程,但还没有完全理解它的语法部分。我发现的大多数东西只是解释它是如何工作的(两个过程:父子等),但non很好地解释了如何在代码中应用它。

有人能解释一下我是如何使用fork()语法的吗?

发送HTTP响应后继续执行PHP

http://www.onlinetechtutorials.com/2014/06/how-to-run-php-code-asynchronously.html

http://php.net/manual/en/function.pcntl-fork.php(更通用)

从服务器端:https://www.youtube.com/watch?v=xVSPv-9x3gk

编辑

我做对了吗?

<?php   
// Registers a new keyword for prod to the DB. 
public function add_keyword() {
    $keyword_p = $this->input->post('key_word');
    $prod      = $this->input->post('prod_name');
    $prod      = $this->kas_model->search_prod_name($prod);
    $prod      = $prod[0]->prod_id;
    $country   = $this->input->post('key_country');
    $keyword = explode(", ", $keyword_p);
    var_dump($keyword); 
    $keyword_count = count($keyword);
    echo "the keyword count: $keyword_count";
    for ($i=0; $i < $keyword_count ; $i++) { 
        // create your next fork
        $pid = pcntl_fork();
        if(!$pid){
            //*** get new vars from $keyword_count
            //*** run API functions to get new data_arrays
            //*** inserts new data for each $keyword_count to the DB 
            print "In child $i'n";
            exit($i);
            // end child
        }
    }
    // we are the parent (main), check child's (optional)
    while(pcntl_waitpid(0, $status) != -1){
        $status = pcntl_wexitstatus($status);
         echo "Child $status completed'n";
    }
    // your other main code: Redirect to main page. 
    redirect('banana/kas'); 
}
?>

在循环中使用它不会造成任何问题吗?它会知道如何堆叠每个流程吗?

您必须提到您正在使用的操作系统,因为pcntl扩展在Windows平台上不可用
此外,您必须注意,在web服务器内的Linux/Unix上激活进程控制可能会给您带来意外的结果,因此建议仅使用CLI/CGI模式
请仔细阅读本PCNTL简介

现在,您的代码似乎是正确的,并且实现得很好,但您必须使用--enable-pcntl选项编译PHP,以启用像int pcntl_fork(void)这样的pcntl函数,否则您将获得

致命错误:调用未定义的函数pcntl_fork()

对我来说,以异步方式运行函数/方法的最佳解决方案是使用pthreads,如果你对这个建议感兴趣,我可以通过添加示例以及如何在Windows或Linux平台上安装来编辑我的响应

阅读本文了解如何编译PHP

在pcntl_fork()之后有一个fork,请检查$pid,然后可以使用它。对更多的fork重复此操作。

<?php
    for($i = 1; $i <= 3; ++$i){
        // create your next fork
        $pid = pcntl_fork();
        if(!$pid){
            // begin child, your execution code
            sleep(1);
            print "In child $i'n";
            exit($i);
            // end child
        }
    }
    // we are the parent (main), check child's (optional)
    while(pcntl_waitpid(0, $status) != -1){
        $status = pcntl_wexitstatus($status);
        echo "Child $status completed'n";
    }
    // your other main code
?>

对于异步http请求,可以使用multicrl:http://php.net/manual/en/function.curl-multi-init.php

据我所知,您可以通过两种方式实现这一点。。。

使用:

  • P螺纹
  • Amphp
  • Pthreads是一个并行处理库,而amp是一个纯异步框架。。。

    因此,使用pthreads的方法是首先下载/启用pthreadss扩展名,并在php.ini文件中添加extension=/path/to/pthread.so。。。

    然后创建一个类,该类扩展Thread类并覆盖方法run,并将所有内容放入其中,这是您想要并行执行的。

    所以为了你的特定目的,这个类可以是这样的:

    <?php
    class Inserter extends Thread {
        public $db_con = null;
        public $data;
        public function __construct($db_connection, $data) {
            $this->db_con = $db_connection;
            $this->data = data;
        }
        private function run() {
            // use your logic to insert the data...
        }
    }
    

    要使用它,只需实例化类,并将DB连接变量和要处理的数据放入ctor中。并调用对象的start方法。类似:

    $inserter = new Inserter($dbConn, $data);
    $inserter->start();
    

    其中$dbConn存储DB连接,$data存储必要的数据。

    就是这样…