codeigniter — PHP + fork (): как запустить форк в коде PHP

Я запускаю свой код на CodeIgniter — Ubuntu Server.

Я искал асинхронные способы запуска функций.

Это моя функция:

<?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, но не совсем понял его синтаксическую часть. Большинство вещей, которые я нашел, были просто объяснениями того, как это работает (2 процесса: parent-child ect ‘), но не дали хорошего объяснения того, как применять это в коде.

Может кто-нибудь объяснить, как я работаю с синтаксисом fork ()?

Продолжить выполнение PHP после отправки HTTP-ответа

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');

}
?>

Это не вызовет никаких проблем с использованием этого внутри цикла? это будет знать, чтобы сложить каждый процесс?

3

Решение

Вы должны указать, какую операционную систему вы используете, потому что расширения pcntl недоступны на платформе Windows
Также вы должны знать, что активация управления процессами в Linux / Unix на веб-сервере может дать вам неожиданные результаты, поэтому только CLI / CGI Режим рекомендуется использовать PCNTL
Пожалуйста, внимательно прочитайте это PCNTL Введение

Теперь ваш код кажется правильным и хорошо реализованным, но вы должны скомпилировать PHP с этой опцией --enable-pcntl включить функции pcntl, такие как int pcntl_fork(void) в противном случае вы получите

Неустранимая ошибка: вызов неопределенной функции pcntl_fork ()

Для меня лучшим решением для запуска функций / методов асинхронным способом является использование Pthreads, если вы заинтересованы в этом совете, я могу отредактировать свой ответ, добавив примеры и как установить его на платформах Windows или Linux

Читать Эта статья уметь компилировать PHP

2

Другие решения

У вас есть один форк после вашего pcntl_fork (), проверьте $ pid и затем вы можете использовать его. Повторите для получения дополнительных вилок.

<?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-запросов вы можете использовать multicurl: http://php.net/manual/en/function.curl-multi-init.php

1

Насколько я знаю, вы можете достичь этого двумя способами …

Использование:

  • Pthreads
  • Amphp
  • Pthreads — это библиотека параллельной обработки, а amp — это чисто асинхронная среда …

    Таким образом, способ использования pthreads заключается в том, чтобы сначала загрузить / включить расширение pthreads и добавить extension=/path/to/pthread.so в файле php.ini …

    А затем создать класс, который расширяет 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...
    }
    }
    

    Чтобы использовать это, просто создайте экземпляр класса, поместите переменную соединения с БД и данные для обработки в ctor. И вызвать метод запуска объекта. Подобно:

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

    куда $dbConn хранит соединение с БД и $data хранит необходимые данные.

    И это все…

    0
    По вопросам рекламы [email protected]