Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Еще раз о многопоточности
 
 автор: KPETuH   (22.02.2007 в 10:58)   письмо автору
 
 

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

   
 
 автор: KPETuH   (22.02.2007 в 13:04)   письмо автору
 
   для: KPETuH   (22.02.2007 в 10:58)
 

ап

   
 
 автор: ZuArt   (22.02.2007 в 13:48)   письмо автору
 
   для: KPETuH   (22.02.2007 в 13:04)
 

одновресменно ОБРАБАТЫВАТЬ полученные данные не выйдет - в PHP многопоточность не реализована... а обработка полученных данных - это все-таки код скрипта и тут уже неважно, сколько времени уходит на получение данных... а вообще - можно попробовать с помощью логики немного оптимизировать...

запрос - ожидание данных - получение данных 1 - запрос новых данных - обработка данных 1 - получение данных 2 - запрос новых данных - ...

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

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

<?
$ok 
=array();

$hdr[1] = сокет+запрос (url1)
$hdr[2] = сокет+запрос (url2)
...
$hdr[N] = сокет+запрос (urlN)

while(
count($ok) < count($hdr))
{
 for (
$i=0$i<count($hdr); $i++)
 {
  if(isset(
$ok[$i])) // если данные по сокету уже обработаны - пропускаем его...
   
continue;
  
читаем из $hdr[iв буфер $buff[$i];
  
если получены последние данные из $hdr[$i]
    
$ok[$i] = обработка $buff[$i]; // результат обработки помещаем в соответствующий элемент массива
 
};
};

закрываем сокеты $hrd[...]
?>

что-то типа такого...

   
 
 автор: KPETuH   (22.02.2007 в 14:07)   письмо автору
 
   для: ZuArt   (22.02.2007 в 13:48)
 

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

все же хотелось бы услышать немногои про неблокирующие сокеты что это такое и с чем его едяи и как особенности у них

   
 
 автор: ZuArt   (22.02.2007 в 14:16)   письмо автору
 
   для: KPETuH   (22.02.2007 в 14:07)
 

вот кажется функция fsockopen как раз открывает сокеты асинхронно, т.е. она не ожидает получения всех данных.. они просто наполняют буфер по мере поступления, а код скрипта выполняется дальше... а данные можно забрать из буфера в любое УДОБНОЕ время... даже кусками можно забирать... обработать - прочитать следующуу порцию...

   
 
 автор: KPETuH   (27.02.2007 в 10:00)   письмо автору
 
   для: ZuArt   (22.02.2007 в 14:16)
 

Победил проблему с помошью неблокирующих сокетов...Скорость отработки скрипта увеличилась с 2-3 минут до 10-20 секунд. :) Спасибо за помощь.

   
 
 автор: ZuArt   (27.02.2007 в 10:21)   письмо автору
 
   для: KPETuH   (27.02.2007 в 10:00)
 

=))) поздравляю ;) а заодно и код сюда попрошу ;) - мне лично не повредит его добавить в свою библиотеку ;)

   
 
 автор: KPETuH   (27.02.2007 в 12:00)   письмо автору
 
   для: ZuArt   (27.02.2007 в 10:21)
 

к сожалению код привести не могу так как там много конфиденциальной информации но за основу взят вот этот код


<?php
$sockets 
= array();
$done false;
// будем работать, к примеру с набором
// ключевых слов
$keywords fopen(”keywords.txt”“r”);
// приступаем к многопоточной работе
while (!$done)
{
    
// если обнаружен файл,
    // то прекращаем выполнение скрипта
    
if (file_exists(”stop-file”))    die;
    
// если число запущенных потоков меньше
    // разрешенного максимума
    // то запускаем потоки еще
    
if ($max_threads count($sockets))
    {
        if (!
feof($keywords))
        {
            
$buffer = array();
            
// читаем ключевое слово
            // в реальности в этот массив можно
            // положить очень много всего
            // а не только одно ключевое слово…
            
$buffer[] = trim(fgets($keywords));
            
// задаем данные для запуска сокета
            // request.php - это тот файл,
            // которые делает “дело”
            
$query_url $path “request.php”;
            
$url_info parse_url($query_url);
            
$url_info[port] = ($url_info[port]) ? $url_info[port] : 80;
            
$url_info[path] = ($url_info[path]) ? $url_info[path] : /;
            
$url_info[query] = ($url_info[query]) ? ?” $url_info[query] : “”;
            
// пакуем данные для передачи
            // в генерирующий скрипт
            // использование serialize очень удобно,
            // так как позволяет
            // залить в request.php мегабайты данных
            
$request serialize($buffer);
            
// формируем запрос для передачи по сокету
            
$query “POST ” $url_info[path] . ” HTTP/1.1\r\n”;
            
$query $query “Content-Typetext/xml\r\n”;
            
$query $query “Host” $url_info[host] . \r\n”;
            
$query $query “Content-length” . (strlen($request)) . \r\n\r\n”;
            
$query $query $request;
            
// создаем сокет, переводим его
            // в неблокирующий режим и запускаем
            // обработчик запросов
            
$errno 0;
            
$error “”;
            
$socket fsockopen($url_info[host], $url_info[port], $errno$error30);
            
stream_set_blocking($socket0);
            
stream_set_timeout($socket3600);
            
fputs($socket$query);
            
// запоминаем запущенный сокет
            
$sockets[md5(time())] = $socket;
        }
    }
    
// читаем данные из сокета. формально они нам
    // не нужны, но это позволяет
    // отработать обработчкику запросов
    
reset($sockets);
    while (
$socket current($sockets))
    {
        if (
feof($socket))
        {
            
// убиваем сокет, который отработал
            
unset($sockets[key($sockets)]);
        }
        else
        {
            
// читаем данные из сокета
            
$temp fgets($socket1000);
        }
        
// обрабатываем следующий сокет
        
next($sockets);
    }
    
// делаем небольщую задержку,
    // иначе загруженность сервера
    // приближается к 100 процентам 

//не знаю как загрузка процессора но без паузы в несколько микросекунд работать отказывается 
    
sleep(1);
    
// если нет активных сокетов, то можно выходить
    
if (count($sockets) == 0)
    
$done true;
}
fclose($keywords);
?>

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования