Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Многопоточность на PHP (https://forum.antichat.xyz/showthread.php?t=98635)

Shaitan-Devil 30.12.2008 12:29

Многопоточность на PHP
 
Введение
Решил написать о многопоточности в PHP. Иногда бывает,что работа выполняется быстрее в нескольких потоках. Полноценную многопоточность как в Perl в PHP можно организовать с натяжкой. Но все же существует несколько способов
1)Запуск нескольких копий скрипта с помощью функции system
Код:

system("/usr/local/bin/php -f index.php par1 par2&");
Но этот вариант не практичный. Т.к. Нужен сервер с огромным каналом и огромным количеством Оперативной Памяти.
2)PHP Thread
Чесnно говоря метод для меня новый.НО как оказалаось весьма полезный.
master.php
Код:

<?php
$array = array(    /*Создаем массив*/
0 => 'thread',
1 => 'hello',
2 => 'world');
thread_set('mySharedVar', $array);/*Расшариваем его для thread.php*/
thread_include('thread.php');/*Инклдуим thread.php*/
sleep(3);/*Ждем 3 секунды пока выполняется*/
echo 'Done';/*Выводим Done*/
?>

thread.php
Код:

<?php
$array = thread_get('mySharedVar');
print_r($array);
sleep(5);
echo 'Done';
?>

Честно стибрено Отсюда
3)Использование функции pcntl для организации (распараллеливания) процессов.
Основная функция
Код:

int pcntl_fork ( void )
Функция для создания дочерних процессов от основного.
Пример с мануала по PHP.
Код:

<?php

$pid*=*pcntl_fork();
if*($pid*==*-1)*{
*****die('could*not*fork');
}*else*if*($pid)*{
*****//*we*are*the*parent
*****pcntl_wait($status);*//Protect*against*Zombie*children
}*else*{
*****//*we*are*the*child
}

?>

Фунция pcntl_alarm(тайм аут). Дает сигнал следующему процессу через указанное количество секунд
Пример с мануала по PHP.
Код:

<?php
*** declare(ticks = 1);

*** function signal_handler($signal) {
** * ** print "Caught SIGALRM\n";
** * ** pcntl_alarm(5);
*** }

*** pcntl_signal(SIGALRM, "signal_handler", true);
*** pcntl_alarm(5);

*** for(;;) {
*** }

?>

pcntl_exec() Запуск еще одной программы одновременно с использованием скрипта. Можно юзать для запуска копии скрипта. Альтернатива 1 варианту
Код:

pcntl_exec("/usr/local/bin/php -f thread.php");
Скомбинировав эти фунции можно сделать многпоточность. Кстати, pcntl -это модуль, и его в стандартной сборке PHP нет.
Многпоточность в контексте сетевого взаимодействия
4)С помощью cURL(curl_multi)
Код:

$mh=curl_multi_init();//Открываем сессию curl_multi
// выполняем запрос
$running = null;
* do {
* * curl_multi_exec($mh, $running);
* } while($running> 0);
*
* // получаем данные и уничтожаем дискриптор
* foreach($curly as $id => $c) {
* * $result[$id] = curl_multi_getcontent($c);
* * curl_multi_remove_handle($mh, $c);
* }
*
* // закрываем многосложный дескриптор
* curl_multi_close($mh);

5)Неблокируемые сокеты
Можно использовать уже готовые классы с неблокируемыми сокетами,вы их без труда найдете если погуглите)
Либо
Код:

while(true)
{
//Код
if(max_threads=count($sock))
{
//Код
}
//Создаем сокет
  $errno = 0;
            $error = “”;

            $socket = fsockopen($url_info[host], $url_info[port], $errno, $error, 30);
            stream_set_blocking($socket, 0);
            stream_set_timeout($socket, 3600);
            fputs($socket, $query);

            // запоминаем запущенный сокет

            $sockets[md5(time())] = $socket;

Заключение
Ну вот в приницпе и все. Знаю,что написал бред,подкорректируйте плз.
Материал по теме
_http://habrahabr.ru/blogs/php/40545/ - Еще одна реализация многопоточности на PHP
_http://habrahabr.ru/blogs/php/40245/ - Эмуляция многопоточности в PHP
_http://habrahabr.ru/blogs/php/40432/ - Многопроцессовые демоны на PHP

Qwazar 30.12.2008 12:46

Shaitan-Devil, имхо для статьи недостаточно подробно + для pcntl_fork не написаны методы прострелить себе ногу. Т.е. то на чём обязательно проколятся новички, при попытке её использования на практике.

groundhog 30.12.2008 13:14

Наверное, создатели CURL в гробу перевернулись, когда их детище поставили в один ряд с функциями pcntl_*. Как это можно сравнивать? Да, это многопоточность, но в контексте сетевого взаимодействия... В общем было миллиард статей на эту тему, это одна из худших...

От себя дополню:

http://github.com/danhen/php_threads/tree/master

[Raz0r] 30.12.2008 15:21

На античате традиция - раз в год кто-нибудь пишет про многопоточность в php =)
По сабжу: в примере "Запуск нескольких копий скрипта с помощью функции system" нет даже символа &, обозначающего переход выполнения команды в бэкграунд, т.е. без ожидания ее завершения. В твоем примере этого нет.

"Использование функции pcntl для организации (распараллеливания) процессов."
Спасибо мануал мы тоже умеем читать. Хотя бы свои наработки показал бы.

"С помощью cURL(curl_multi)"
среди всех перечисленных способов этот наименее всего подходит под понятие организации многопоточности. К этой же серии также относятся неблокирующие сокеты, о которых вообще ничего не сказано в твоей статье.
И как упомянул groundhog ничего нет про php_threads
В общем слабо.
p.s. выйдет PHP6 тогда и поговорим о многопоточности

Qwazar 30.12.2008 16:18

Цитата:

Сообщение от geforse
Запускайте 20 копий скрипта ... вот вам и многопоточность)

Угу, а синхронизация при помощи бд :)))

Shaitan-Devil 30.12.2008 16:20

Спасибо за конструктивную критику, будем фиксить баги.

gibson 30.12.2008 18:21

Цитата:

функции pcntl
забыл дописать, что под виндой не работает.

http://php.su/functions/?cat=pcntl

все остальное от лукавого.

KaZ@NoVa 30.12.2008 19:39

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

KaZ@NoVa 30.12.2008 19:55

Цитата:

Сообщение от baltazar
дааа,пхп конечно не перл=\,многопоточности как такой и нету,ее можно симулировать с помощью неблокирующихся сокетов и библиотек,типа мультикурл

изучил довольно много информации по данной теме и пришел к выводу,нужно реализовывать на неблокируемых сокетах (мультикурл мне не понравился тем, что он может обрабатывать только пачками, т.е. при обработке 100 урлов на конечном этапе имеем снижение производительности - допустим 98 уже обработалось и вся система ждет обработку каких то 2х тормозных урлов, в конечном итоге теряя время).

Плотно пошарив в инете нашёл таки класс AunoAsyncHttp, на котором в дальнейшем я и выстраивал все свои многопоточные скрипты.

Shaitan-Devil 30.12.2008 20:46

Пофиксил некоторые баги.


Время: 02:24