Как реализовать многопоточность в php? [Дубликат]

Вы можете установить выходной дисплей в соответствии с вашей текущей шириной терминала:

pd.set_option('display.width', pd.util.terminal.get_terminal_size()[0])
325
задан Lance Roberts 22 October 2011 в 01:47
поделиться

18 ответов

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

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

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

http: //localhost/test/verifysession.php? sessionid = [ правильный id]

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);
15
ответ дан 4 revs, 3 users 70% 5 September 2018 в 09:57
поделиться

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

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

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

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

4
ответ дан Anil 5 September 2018 в 09:57
поделиться

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

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

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

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

Предупреждение. Расширение 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);
}
356
ответ дан duskwuff 5 September 2018 в 09:57
поделиться

Пока вы не можете нить, у вас есть определенная степень управления процессом в 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 5 September 2018 в 09:57
поделиться

Как насчет pcntl_fork?

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

2
ответ дан Jarrod 5 September 2018 в 09:57
поделиться

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

8
ответ дан Jeffrey Kevin Pry 5 September 2018 в 09:57
поделиться

У вас может быть опция:

  1. multi_curl
  2. Можно использовать системную команду для того же
  3. Идеальный сценарий, создать функцию потоковой передачи на языке C и компилировать / настраивать в PHP. Теперь эта функция будет функцией PHP.
2
ответ дан Joe McBride 5 September 2018 в 09:57
поделиться

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

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

uname -a

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

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

0
ответ дан Martin Vahi 5 September 2018 в 09:57
поделиться

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

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

pclose(popen("start /B ". $script_exec, "r"));
-2
ответ дан Mubashar Ahmad 5 September 2018 в 09:57
поделиться

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

2
ответ дан Palec 5 September 2018 в 09:57
поделиться

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

5
ответ дан Pete 5 September 2018 в 09:57
поделиться

, используя потоки, становится возможным благодаря расширению PECLs pentl

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

8
ответ дан pinkal vansia 5 September 2018 в 09:57
поделиться

Многопоточность означает одновременное выполнение нескольких задач или процессов, мы можем достичь этого в 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

-3
ответ дан Pir Abdul 5 September 2018 в 09:57
поделиться

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

2
ответ дан Robin Daugherty 5 September 2018 в 09:57
поделиться

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

3
ответ дан Sheldmandu 5 September 2018 в 09:57
поделиться

Для многопоточности HTTP с использованием GuzzleHttp (поскольку pthreads могут не работать в веб-приложениях), см. ниже блог - https://blog.madewithlove.be/post/concurrent-http-requests/

0
ответ дан Som 5 September 2018 в 09:57
поделиться

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

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

3
ответ дан Unsigned 5 September 2018 в 09:57
поделиться

почему вы не используете 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]);
    }
}
26
ответ дан Uwe Keim 5 September 2018 в 09:57
поделиться
Другие вопросы по тегам:

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