
![]() |
Здравствуйте Гость ( Вход | Регистрация ) |
|
|
|
![]() ![]() ![]() |
![]() |
|
![]() Новичок ![]() Профиль Группа: Пользователь Сообщений: 1 Пользователь №: 46657 На форуме: Карма: ![]() |
Возникла у меня задача, в рамках которой нужно периодически опрашивать достаточно большое число веб-страниц, причём делать это быстро и в то же время не сильно грузя процессор, да и всю систему в целом, так как работать должно на довольно слабой машине, на которой и без того много всякого крутится.
Подобные задачи на PHP раньше решать не приходилось, поэтому полез читать документацию по curl_* (и, в частности, по curl_multi_*). Почитал, написал код. Не работает. Помучился-поэкспериметировал сначала сам - не помогло. Поизучал Интернет, ужаснулся увиденному, но некий работающий вариант из кусочков вселенского <?php Всё, вроде бы, хорошо, работает, и даже довольно шустро, только вот процессор во время этой своей работы грузит неслабо. А это противоречит условиям задачи, да и вообще не соответствует логике алгоритма и обещаниям документации. Начал разбираться и обнаружил ужасы. Во-первых, вызов curl_multi_select(), вместо того, чтобы долго висеть в ожидании поступления ответов на запросы, завершается моментально и возвращает -1, что означает ошибку в общении со стеком операционки. И хотя почти вся остальная часть цикла при этом пропускается, процессор всё равно грузится. И только после изрядного количества оборотов цикла -1 меняется на положительное число (ответ от сервера поступил). Во-вторых, даже когда curl_multi_select() говорит, что данные пришли, curl_multi_info_read() возвращает false ("Нет никаких ответов"). И ещё сколько-то оборотов цикла должны прокрутиться, прежде чем curl_multi_info_read() соизволит-таки заметить пришедшие ответы. А значит, ещё бессмысленная нагрузка на процессор. В-третьих, даже если curl_multi_info_read() увидела несколько (3-4-5) пришедших ответов, вовсе не факт, что их все удастся вычитать во внутреннем цикле. Нередко вычитываются только часть из пришедших, а остальные - на следующих проходах внешнего цикла. Соответственно, вопросы: 1. Как сделать, чтобы curl_multi_select() висела до прихода ответов (как того обещает документация)? 2. Как сделать, чтобы curl_multi_info_read() вычитывала всё, что пришло, не откладывая часть "на потом"? Частично я проблему бессмысленных циклов сгладил, вставив в цикле задержку на полсекунды (usleep(500000)) перед вызовом curl_multi_select(). Но это же костыль, а хочется, чтобы было по-человечески. |
![]() |
![]() ![]() ![]() |