Как можно использовать многопоточность в приложениях PHP

Поскольку ваш класс Child расширяет ваш Parent класс, все свойства и методы, которые либо public, либо protected в классе Parent будут видны классом Child, как если бы они были определяемый в классе Child - и наоборот.

Когда класс Child extends класса Parent, его можно увидеть как "Child a Parent " - это означает, что Child обладает свойствами Parent, если только он не переопределяет их другим способом.

(Кстати, обратите внимание, что« parent "- это зарезервированное ключевое слово в PHP, что означает, что вы не можете назвать класс с таким именем)

Вот краткий пример« родительского »класса:

class MyParent {
    protected $data;
    public function __construct() {
        $this->someMethodInTheParentClass();
    }
    protected function someMethodInTheParentClass() {
        $this->data = 123456;
    }
}

И это «дочерний» класс:

class Child extends MyParent {
    public function __construct() {
        parent::__construct();
    }
    public function getData() {
        return $this->data; // will return the $data property 
                            // that's defined in the MyParent class
    }
}

Это можно использовать следующим образом:

$a = new Child();
var_dump($a->getData());

И вы получите результат:

int 123456

Это означает, что свойство $data, определенное в классе MyParent и инициализированное в методе того же класса MyParent, доступно классу Child, как если бы оно было его.

Чтобы сделать вещи простыми: поскольку Child "является" MyParent, ему не нужно ke ep указатель на ... сам; -)

369
задан Lance Roberts 22 October 2011 в 00:47
поделиться

17 ответов

Может быть, я что-то пропустил, но exec не работал для меня асинхронно в среде Windows, которую я использовал в Windows, и это работало как прелесть;)

$script_exec = "c:/php/php.exe c:/path/my_ascyn_script.php";

pclose(popen("start /B ". $script_exec, "r"));
-2
ответ дан Mubashar Ahmad 22 October 2011 в 00:47
поделиться

Многопоточность возможна в php

Да, вы можете сделать многопоточность в PHP с pthreads

Из документации PHP :

pthreads - это объектно-ориентированный API, который предоставляет все инструменты, необходимые для многопоточности в PHP. Приложения PHP могут создавать, читать, писать, выполнять и синхронизировать с потоками, рабочими и потоковыми объектами.

Предупреждение : Расширение pthreads нельзя использовать в среде веб-сервера. Поэтому многопоточность в PHP должна оставаться только для приложений на основе CLI.

Простой тест

#!/usr/bin/php
<?php
class AsyncOperation extends Thread {

    public function __construct($arg) {
        $this->arg = $arg;
    }

    public function run() {
        if ($this->arg) {
            $sleep = mt_rand(1, 10);
            printf('%s: %s  -start -sleeps %d' . "\n", date("g:i:sa"), $this->arg, $sleep);
            sleep($sleep);
            printf('%s: %s  -finish' . "\n", date("g:i:sa"), $this->arg);
        }
    }
}

// Create a array
$stack = array();

//Initiate Multiple Thread
foreach ( range("A", "D") as $i ) {
    $stack[] = new AsyncOperation($i);
}

// Start The Threads
foreach ( $stack as $t ) {
    $t->start();
}

?>

Первый запуск

12:00:06pm:     A  -start -sleeps 5
12:00:06pm:     B  -start -sleeps 3
12:00:06pm:     C  -start -sleeps 10
12:00:06pm:     D  -start -sleeps 2
12:00:08pm:     D  -finish
12:00:09pm:     B  -finish
12:00:11pm:     A  -finish
12:00:16pm:     C  -finish

Второй запуск

12:01:36pm:     A  -start -sleeps 6
12:01:36pm:     B  -start -sleeps 1
12:01:36pm:     C  -start -sleeps 2
12:01:36pm:     D  -start -sleeps 1
12:01:37pm:     B  -finish
12:01:37pm:     D  -finish
12:01:38pm:     C  -finish
12:01:42pm:     A  -finish

Реальный мир Пример

error_reporting(E_ALL);
class AsyncWebRequest extends Thread {
    public $url;
    public $data;

    public function __construct($url) {
        $this->url = $url;
    }

    public function run() {
        if (($url = $this->url)) {
            /*
             * If a large amount of data is being requested, you might want to
             * fsockopen and read using usleep in between reads
             */
            $this->data = file_get_contents($url);
        } else
            printf("Thread #%lu was not provided a URL\n", $this->getThreadId());
    }
}

$t = microtime(true);
$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));
/* starting synchronization */
if ($g->start()) {
    printf("Request took %f seconds to start ", microtime(true) - $t);
    while ( $g->isRunning() ) {
        echo ".";
        usleep(100);
    }
    if ($g->join()) {
        printf(" and %f seconds to finish receiving %d bytes\n", microtime(true) - $t, strlen($g->data));
    } else
        printf(" and %f seconds to finish, request failed\n", microtime(true) - $t);
}
393
ответ дан duskwuff 22 October 2011 в 00:47
поделиться

Вы можете иметь опцию:

  1. multi_curl
  2. Можно использовать системную команду для одного и того же
  3. Идеальный сценарий - создать функцию потоков на языке C и скомпилировать / настроить в PHP. Теперь эта функция будет функцией PHP.
2
ответ дан Joe McBride 22 October 2011 в 00:47
поделиться

pcntl_fork не будет работать в среде веб-сервера, если в нем включен безопасный режим . В этом случае он будет работать только в CLI-версии PHP.

2
ответ дан Palec 22 October 2011 в 00:47
поделиться

Многопоточность означает выполнение нескольких задач или процессов одновременно, мы можем достичь этого в php, используя следующий код, хотя прямого способа достижения многопоточности в php нет, но мы можем достичь почти таких же результатов следующим образом.

chdir(dirname(__FILE__));  //if you want to run this file as cron job
 for ($i = 0; $i < 2; $i += 1){
 exec("php test_1.php $i > test.txt &");
 //this will execute test_1.php and will leave this process executing in the background and will go         

 //to next iteration of the loop immediately without waiting the completion of the script in the   

 //test_1.php , $i  is passed as argument .

}

Test_1.php

$conn=mysql_connect($host,$user,$pass);
$db=mysql_select_db($db);
$i = $argv[1];  //this is the argument passed from index.php file
for($j = 0;$j<5000; $j ++)
{
mysql_query("insert  into  test   set

                id='$i',

                comment='test',

                datetime=NOW() ");

}

Это выполнит test_1.php два раза одновременно, и оба процесса будут выполняться в фоновом режиме одновременно, так что таким образом вы можете добиться многопоточности в php.

Этот парень проделал действительно хорошую работу. Многопоточность в php.

.
-5
ответ дан Pir Abdul 22 October 2011 в 00:47
поделиться

Класс Thread доступен, поскольку PECL pthreads ≥ 2.0.0.

3
ответ дан Robin Daugherty 22 October 2011 в 00:47
поделиться

Как насчет pcntl_fork?

проверьте нашу страницу руководства для примеров: PHP pcntl_fork

3
ответ дан Jarrod 22 October 2011 в 00:47
поделиться

На момент написания моего текущего комментария я не знал о потоках PHP. Я сам пришел к поиску ответа, но один из обходных путей заключается в том, что PHP-программа, которая получает запрос от веб-сервера, делегирует всю формулировку ответа консольному приложению, которое сохраняет свои выходные данные, ответ на запрос, в двоичный файл. и программа PHP, которая запустила консольное приложение, возвращает этот двоичный файл побайтно в качестве ответа на полученный запрос. Консольное приложение может быть написано на любом языке программирования, работающем на сервере, включая те, которые имеют надлежащую поддержку потоков, в том числе программы на C ++, использующие OpenMP.

Один ненадежный, грязный трюк состоит в том, чтобы использовать PHP для выполнения консольного приложения «uname»,

uname -a

и распечатать вывод этой консольной команды в вывод HTML, чтобы узнать точную версию. серверного программного обеспечения. Затем установите точно такую ​​же версию программного обеспечения на экземпляр VirtualBox, скомпилируйте / соберите все необходимые автономные, предпочтительно статические, двоичные файлы, а затем загрузите их на сервер. С этого момента приложение PHP может использовать эти двоичные файлы в роли консольного приложения, которое имеет правильную многопоточность. Это грязный, ненадежный обходной путь в ситуации, когда администратор сервера не установил все необходимые реализации языка программирования на сервер. Остерегайтесь того, что при каждом запросе PHP-приложение получает консольное (-ие) приложение (-ы) / exit / get_killed.

Что касается того, что администраторы хостинг-службы думают о таких шаблонах использования сервера, я думаю, это сводится к культуре. В Северной Европе поставщику услуг необходимо предоставить то, что было объявлено, и если было разрешено выполнение консольных команд и разрешена загрузка файлов, не относящихся к вредоносным программам, и поставщик услуг имеет право уничтожить любой процесс сервера через несколько минут или даже через 30 секунд. то у администраторов хостинг-сервиса нет никаких аргументов для формирования правильной жалобы. В Соединенных Штатах и ​​Западной Европе ситуация / культура очень разные, и я считаю, что есть большой шанс, что в США и / или Западной Европе поставщик услуг хостинга откажется обслуживать клиентов услуг хостинга, которые используют описанный выше прием. Это только мое предположение, учитывая мой личный опыт работы с хостинг-службами в США и то, что я слышал от других о хостинг-сервисах в Западной Европе. На момент написания моего текущего комментария (2018_09_01) я ничего не знаю о культурных нормах южно-европейских поставщиков услуг хостинга, администраторов южно-европейских сетей.

0
ответ дан Martin Vahi 22 October 2011 в 00:47
поделиться

использование потоков стало возможным благодаря расширению pthreads PECL

http://www.php.net/manual/en/book.pthreads.php

9
ответ дан pinkal vansia 22 October 2011 в 00:47
поделиться

почему бы тебе не использовать popen ?

for ($i=0; $i<10; $i++) {
    // open ten processes
    for ($j=0; $j<10; $j++) {
        $pipe[$j] = popen('script2.php', 'w');
    }

    // wait for them to finish
    for ($j=0; $j<10; ++$j) {
        pclose($pipe[$j]);
    }
}
35
ответ дан Uwe Keim 22 October 2011 в 00:47
поделиться

Вы можете использовать exec () для запуска сценария командной строки (например, командной строки php), и если вы передадите вывод в файл, тогда ваш сценарий не будет ждать завершения команды.

Я не совсем помню синтаксис php CLI, но вы бы хотели что-то вроде:

exec("/path/to/php -f '/path/to/file.php' | '/path/to/output.txt'");

Я думаю, что для многих серверов общего хостинга exec () по умолчанию отключен по соображениям безопасности, но, возможно, стоит попробовать.

5
ответ дан Anil 22 October 2011 в 00:47
поделиться

Я знаю, что это старый вопрос, но для людей, которые ищут, есть расширение PECL, написанное на C, которое теперь дает возможность многопоточности PHP, оно находится здесь https://github.com/krakjoe/pthreads

8
ответ дан Jeffrey Kevin Pry 22 October 2011 в 00:47
поделиться

Вы можете смоделировать потоки. PHP может запускать фоновые процессы через popen (или proc_open). Эти процессы могут быть переданы через stdin и stdout. Конечно, эти процессы сами могут быть php-программами. Это, вероятно, так близко, как вы получите.

5
ответ дан Pete 22 October 2011 в 00:47
поделиться

В зависимости от того, что вы пытаетесь сделать, вы также можете использовать curl_multi для этого.

3
ответ дан Sheldmandu 22 October 2011 в 00:47
поделиться

Я знаю, что это старый, но вы можете посмотреть на http://phpthreadlib.sourceforge.net/

Он поддерживает двунаправленную связь между потоками, а также имеет встроенный средства защиты от уничтожения дочерних потоков (предотвращения сирот).

3
ответ дан Unsigned 22 October 2011 в 00:47
поделиться

Хотя вы не можете создавать потоки, у вас есть некоторая степень контроля над процессами в php. Здесь полезны два набора функций:

Функции управления процессом http://www.php.net/manual/en/ref.pcntl.php

Функции POSIX http://www.php.net/manual/en/ref.posix.php

Вы можете форкнуть ваш процесс с помощью pcntl_fork - возвращая PID ребенка. Затем вы можете использовать posix_kill для удаления этого PID.

Тем не менее, если вы убьете родительский процесс, то должен быть отправлен сигнал дочернему процессу, говорящий о его смерти. Если сам php не распознает это, вы можете зарегистрировать функцию для управления им и выполнить чистый выход с помощью pcntl_signal.

10
ответ дан J.D. Fitz.Gerald 22 October 2011 в 00:47
поделиться

Многопоточность недоступна в стандартном PHP, но возможно параллельное программирование с использованием HTTP-запросов в качестве асинхронных вызовов.

С таймаутом curl, установленным на 1, и с использованием того же session_id для процессов, которые вы хотите связать друг с другом, вы можете общаться с переменными сеанса, как в моем примере ниже. С помощью этого метода вы даже можете закрыть свой браузер, а параллельный процесс все еще существует на сервере.

Не забудьте проверить правильный идентификатор сеанса следующим образом:

http: //localhost/test/verifysession.php? sessionid = [ правильный идентификатор]

startprocess.php

$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];

process1.php

set_time_limit(0);

if ($_REQUEST["sessionid"])
   session_id($_REQUEST["sessionid"]);

function checkclose()
{
   global $_SESSION;
   if ($_SESSION["closesession"])
   {
       unset($_SESSION["closesession"]);
       die();
   }
}

while(!$close)
{
   session_start();
   $_SESSION["test"] = rand();
   checkclose();
   session_write_close();
   sleep(5);
}

verifysession.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
var_dump($_SESSION);

closeprocess.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
$_SESSION["closesession"] = true;
var_dump($_SESSION);
21
ответ дан 4 revs, 3 users 70% 22 October 2011 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: