powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / curl_multi
5 сообщений из 5, страница 1 из 1
curl_multi
    #38896635
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильно ли я понимаю принцип работы с многопоточным курлом?
1) набрасываем curl-объекты через curl_multi_add_handle()
2) запускаем все потоки через curl_multi_exec() при этом потоки считаются незапущенными, пока функция возвращает CURLM_CALL_MULTI_PERFORM
3) Ожидаем, пока хоть какой-то объект отработает, для этого вызываем curl_multi_select(). Функция возвращает управление либо когда есть выполненные запросы, либо когда прошел таймаут.
4) вызываем curl_multi_info_read(), смотрим какие запросы выполнились и обрабатываем их
5) если функция curl_multi_select() вернула $still_running = true, то переходим к шагу два. При этом выполненные запросы повторно выполняться не будут.
6) если мне нужно повторно выполнить запрос (например у созданного curl-объекта нужно поменять url), то мне нужно вызвать curl_multi_remove_handle() и curl_multi_add_handle() с одним и тем же curl-объектом

Как-то не совсем логично, поэтому чувствую, что где-то ошибка в понимании

С уважением, Vasilisk
...
Рейтинг: 0 / 0
curl_multi
    #38897220
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Правильно ли я понимаю принцип работы с многопоточным курлом?
1) набрасываем curl-объекты через curl_multi_add_handle()
2) запускаем все потоки через curl_multi_exec() при этом потоки считаются незапущенными, пока функция возвращает CURLM_CALL_MULTI_PERFORM
3) Ожидаем, пока хоть какой-то объект отработает, для этого вызываем curl_multi_select(). Функция возвращает управление либо когда есть выполненные запросы, либо когда прошел таймаут.
4) вызываем curl_multi_info_read(), смотрим какие запросы выполнились и обрабатываем их
5) если функция curl_multi_select() вернула $still_running = true, то переходим к шагу два. При этом выполненные запросы повторно выполняться не будут.
6) если мне нужно повторно выполнить запрос (например у созданного curl-объекта нужно поменять url), то мне нужно вызвать curl_multi_remove_handle() и curl_multi_add_handle() с одним и тем же curl-объектом

Как-то не совсем логично, поэтому чувствую, что где-то ошибка в понимании

С уважением, Vasilisk

мысль1 - чтобы не подвисало как в джаваскрипте изза одного подвисшегго вызова, любая функция по управлению многопоточностью должа давать ответ быстрый. мгновенный в идеале.

мысль2 у нас есть своя работа, и потоки. нам надо при своей работе разбитой на шаги по шагу и потокам давать работать.
иногда своей работы нету, поэтому надо уснуть, пускай работают потоки.

вот и получаем две функции мульти-екзек, и мультиселект.

мысль3 - это как замечание, если ты не понял, из документации это не следует. ты в любое время можешь добавлять есчё потоки, и влюбое время удалять, даже не дожавшись окончания их работы. мульти-курл, это по сути не курл, а менеджер по управлению пулом одиночных курлов.

мысль4 - вот допустим мы хотим по серверам по списку качать логи, и парсить их, результат складывать в отдельный файл.

Тогда мы будем допустим в цикле из уже скачанного файла парсить 10 строчек, и потом делать один вызов мульти_экзека. можно как написанно в пхп документации, делать не один вызов, если ответ функции таков что её есть что делать есчё.
тут уже от фантазии зависит, как ты хочешь синхронизировать работу свою с работой потоков.

если своей нету, тогда да - вызываем в цикле мультиэкзек пока ей есть что делать.
когда уже нечего - наступает ситуация когда и потокам нечего делать и нам, надо уснуть - можно уснуть слипом, но вдруг потокам появиться работа, поэтому лучше уснуть кулд_мульти_селект

всё на самом деле очень логично.

ЗЫ
курл_мульти_селект может дать ответ -1, что означает что она счас не применима. и курл_екзек тоже выдаёт что ему нечего делать... можно в цикле спасить вызовами, грузить просс, но лучше уже слипом уснуть на 50-100 мсек, это значит что менеджер (курл-мульти) выполнил какието вызовы и ждёт ответов, и ему работы нету, и мульти-селект не применим, ибо есчё одиночный курл ни один не стартанул. тоесть если мультиселект пойдёт циклом ждать изменения состояния - то он будет ждать его вечно возможно, так как ни один поток есчё не стартанул, а следовательно возможно и не стартанёт.


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

вообще чтобы лучше это понять, напиши код и поиграйся с ним. чтоб воочию увидеть.
...
Рейтинг: 0 / 0
curl_multi
    #38897349
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я знаком с многопоточным программированием. Мне не понятны следующие моменты
1) multi_select ничего не делает, он только ждет. Т.е. полный аналог WaitForMultipleObjects. Команду на скачивание дает multi_exec, но из-за какой-то особенности реализации нужно ждать пока она не перестанет возвращать CURLM_CALL_MULTI_PERFORM. Так? Или этот код ошибки говорит, что еще не все запросы выполнены и я могу один раз вызвать multi_exec и тут же уснуть в multi_select?

2) в документации после вызова multi_select и обработки результата через info_read опять вызывается multi_exec. Из чего я делаю вывод, что выполненные запросы повторно не выполняются. Я прав? Что мне нужно сделать, чтобы запрос выполнился повторно

3) Таймаут в multi_select - это ждать не более этого времени или подождать это время, а потом посмотреть кто, что сделал?
...
Рейтинг: 0 / 0
curl_multi
    #38897500
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Я знаком с многопоточным программированием. Мне не понятны следующие моменты
1) multi_select ничего не делает, он только ждет. Т.е. полный аналог WaitForMultipleObjects. Команду на скачивание дает multi_exec, но из-за какой-то особенности реализации нужно ждать пока она не перестанет возвращать CURLM_CALL_MULTI_PERFORM. Так? Или этот код ошибки говорит, что еще не все запросы выполнены и я могу один раз вызвать multi_exec и тут же уснуть в multi_select?

2) в документации после вызова multi_select и обработки результата через info_read опять вызывается multi_exec. Из чего я делаю вывод, что выполненные запросы повторно не выполняются. Я прав? Что мне нужно сделать, чтобы запрос выполнился повторно

3) Таймаут в multi_select - это ждать не более этого времени или подождать это время, а потом посмотреть кто, что сделал?

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

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

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
$ch = curl_init($link);
$mt = crul_multi_init();
curl_multi_add($mt,$ch)

$f = fopen('myfile','r');

$read = true;
$multi = true;

while ($read || $multi)
{
if($read)
{
$data = fread($f, 1024);
process_data($data);
$read = !feof($f);
}
else
{
 curl_multi_select($mh);
}

if($multi)
{
curl_multi_exec($mh,$multi);
}

}



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

по хорошему для примера выше, надо сделать функцию типа

Код: php
1.
2.
3.
4.
5.
6.
function curl_multi_exec_t($mh,&$still_running,$timeout)
{
$now = microtime(true);
while ((microtime(true)-$now < $timeout) && (CURL_CALL_MULTI_PERFOM !=curl_multi_exec($mh, $still_running)) && $still_running)

}


и вызывать её, задавая маленький таймаут пока файл читаем, и большой когда уже файл прочитали.

и да кстате, в курле7, там фиг дождёшься ответа мультиперфом. его исключили, так как один чорт пхп програмисты этого момента не поняли и никто не использовал, а то как использовали - только во вред. счас она возвращает CULRM_OK.


опять же, это нудно, но чтоб это всё уяснилось, это лучше поиграться.

посмотреть что будет если в цикле тупо вызывать мультиэкзек например.

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

и посмотри...сколько вызовов на одно и тоже скачивание будет
1)мультиэкзек в цикле
2)мультиэкзек пока возвращает мультиперфом(а она уже не возвращает) потом селект с большим таймаутом
3)тоже что два, но если селект вернул -1, уснуть на 50мс слипом пхпшным.
...
Рейтинг: 0 / 0
curl_multi
    #38897510
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

3) тайм аут это тайм аут, = не больше чем.

2) да, одиночные закачки которые закончились они закончились.
есчё раз - мульти-курл , это не курл, это менеджер потоков курла. ему побую закончилася закачка или нет..ведь не он качает, он лишь даёт сигналы потокам и получает ответы от них.

и кстате, если поток есть, пусть даже работу он закончил, он всёравно с ним работает , правда на холостых, но работает.
тоесть для примера сделай пул на 100 закачек, одну длинную - 10метров, и 99 коротких - по 100 байт, и не вынимай их из пула, и посмотри сколько ты будешь вызово мультиэкзека делать для скачивания 10 метров, и сколько суммарно эти вызовы будут длиться, и другой случай - вынять все 99 закончившиеся мелкие.

поэтому - закончившуюся закачку лучше вынять из пула

если надо чтобы одиночный курл который был добавлен в пулл curl_multi_add
есчё раз отработал, его надо просто есчё раз добавить.

опять же, каждая одиночная закачка ведёт себя как обычно - мульти-курл никак не влияет на неё.

вот единичный курл, ты же можешь заново запустить - можешь, точно также и в режиме мульти, ибо curl_multi - это менеджер пула, он сам к сети вообще никакого значения не имеет. болле того, если посмотреть на описание ответа curl_multi_exec() - то там написано - даже при ответе ОК, ошибки могут быть на отдельных закачках. ибо - курл-мульти, он не качает, не работает по сети, этопросто менеджер потоков.

курл-мульти, это как ядро виндоус, которое организует работу разных програм паралельную на одном процессоре.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / curl_multi
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]