HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ИНФО > Статьи
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 19.09.2010, 15:32
S0meT1me
Новичок
Регистрация: 02.06.2009
Сообщений: 20
С нами: 8916178

Репутация: 24
По умолчанию

I ВСТУПЛЕНИЕ

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

Сразу отмечу, эмулировать многопоточность будем для работы с сетью, не для вычислительных процессов и прочего (ИМХО - здесь PHP не пригоден как интерпритируемый язык в связи со скоростью его выполнения).

Итак, рассмотрим способы реализации многопоточности в ПХП.

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

Такой подход подробно рассмотрен здесь . Стоит так же отметить, такой же подход использует класс функций multi_ библиотеки CURL.

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

Я пошёл по второму пути, развил и доработал его. Разработанный скрипт распределяет входные данные, может работать с несколькими исполняемыми скриптами одновременно, собирает результаты работы скриптов по их завершению.

II РЕАЛИЗАЦИЯ

Функция для запуска эмуляции многопоточности

PHP код:
[COLOR="#000000"][COLOR="#0000BB"]threads_create[/COLOR][COLOR="#007700"](

[/COLOR][COLOR="#0000BB"]$threads[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//число потоков

[/COLOR][COLOR="#0000BB"]$copy_files[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//файлы, нужные для работы каждого потока

[/COLOR][COLOR="#0000BB"]$create_files[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//исходные данные, которые нужно распределить между потоками

[/COLOR][COLOR="#0000BB"]$run_files[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//исполняемые файлы в рамках каждого потока

[/COLOR][COLOR="#0000BB"]$implode_files[/COLOR][COLOR="#FF8000"]//результирующие данные, сформированные каждым из потоков, которые нужно собрать в 1 файл

[/COLOR][COLOR="#007700"])[/COLOR][/COLOR
Вкратце алгоритм работы:

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

PHP код:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]threads_create[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$threads[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$copy_files[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$create_files[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$run_files[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$implode_files[/COLOR][COLOR="#007700"]=array() ) {

[/
COLOR][COLOR="#0000BB"]$cfs[/COLOR][COLOR="#007700"]= array();

foreach([/COLOR][COLOR="#0000BB"]$create_files[/COLOR][COLOR="#007700"]as[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$content[/COLOR][COLOR="#007700"]) {

if( ![/COLOR][COLOR="#0000BB"]is_array[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$content[/COLOR][COLOR="#007700"]) ) {

[/
COLOR][COLOR="#0000BB"]$content[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]file2array[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"]);

} else {

}

[/
COLOR][COLOR="#0000BB"]$cfs[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"]] =[/COLOR][COLOR="#0000BB"]array_rand_slice[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$content[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$threads[/COLOR][COLOR="#007700"]);

}



[/COLOR][COLOR="#0000BB"]$bat[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"@echo off\ncd thread0\n"[/COLOR][COLOR="#007700"];

[/
COLOR][COLOR="#0000BB"]$tdir[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'threads-'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]randstr[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]5[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]mkdir[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$tdir[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]chdir[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$tdir[/COLOR][COLOR="#007700"]);



for
([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"])

[/
COLOR][COLOR="#0000BB"]copy[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'../'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$fname_from[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$dir[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'/'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"]);



foreach
([/COLOR][COLOR="#0000BB"]array_keys[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$cfs[/COLOR][COLOR="#007700"]) as[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"])

[/COLOR][COLOR="#0000BB"]file_put_contents[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$dir[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'/'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]str_replace[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"\n\n"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]implode[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cfs[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"]] [[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]] ) ) );



[/COLOR][COLOR="#0000BB"]$bat[/COLOR][COLOR="#007700"].=[/COLOR][COLOR="#DD0000"]"cd ..\\thread[/COLOR][COLOR="#007700"]{[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]}[/COLOR][COLOR="#DD0000"]\n"[/COLOR][COLOR="#007700"];

foreach([/COLOR][COLOR="#0000BB"]$run_files[/COLOR][COLOR="#007700"]as[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$params[/COLOR][COLOR="#007700"])

[/COLOR][COLOR="#0000BB"]$bat[/COLOR][COLOR="#007700"].=[/COLOR][COLOR="#DD0000"]"start php[/COLOR][COLOR="#0000BB"]$fname[/COLOR][COLOR="#DD0000"][/COLOR][COLOR="#0000BB"]$params[/COLOR][COLOR="#DD0000"]\n"[/COLOR][COLOR="#007700"];

}



[/COLOR][COLOR="#0000BB"]file_put_contents[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'run.bat'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$bat[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]exec[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'run.bat'[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]unlink[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'run.bat'[/COLOR][COLOR="#007700"]);



foreach
([/COLOR][COLOR="#0000BB"]$implode_files[/COLOR][COLOR="#007700"]as[/COLOR][COLOR="#0000BB"]$if[/COLOR][COLOR="#007700"]) {

[/
COLOR][COLOR="#0000BB"]$contents[/COLOR][COLOR="#007700"]= array();

for([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#DD0000"]'do.php'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//какие файлы копировать в папку к каждому потоку

[/COLOR][COLOR="#007700"]),

array(

[/
COLOR][COLOR="#DD0000"]'accs.txt'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'accs.txt'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//какие файлы содержат данные, что надо равномерно распределить между всеми потоками

[/COLOR][COLOR="#007700"]),

array(

[/
COLOR][COLOR="#DD0000"]'do.php'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//исполняемые файлы с набором параметров

[/COLOR][COLOR="#007700"]),

array(

[/
COLOR][COLOR="#DD0000"]'accs.good.txt'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#FF8000"]//файл гуд акков, который надо собрать в результате работы каждого из потоков

[/COLOR][COLOR="#DD0000"]'accs.bad.txt'[/COLOR][COLOR="#FF8000"]//файл бед акков

[/COLOR][COLOR="#007700"])

);

}[/
COLOR][/COLOR
Спасибо за внимание.
 
Ответить с цитированием

  #2  
Старый 19.09.2010, 16:57
Catbert
Познающий
Регистрация: 29.06.2010
Сообщений: 80
С нами: 8353046

Репутация: 10
По умолчанию

Цитата:
Сообщение от None  
Но, существует немало задач, где она необходима. В рамках тематики данного форума это могут быть брутеры, спамеры, граберы, чекеры, инвайтеры, гулялки, заливщики.
И любой адекватный человек использует для этих целей другой язык программирования.

Цитата:
Сообщение от None  
Сразу отмечу, эмулировать многопоточность будем для работы с сетью, не для вычислительных процессов и прочего (ИМХО - здесь PHP не пригоден как интерпритируемый язык в связи со скоростью его выполнения).
Из-за скорости выполнения и нагрузки он и для работы с сетью с такими "потоками" не особо пригоден.

Далее рассмотрим кодэ.

Цитата:
Сообщение от None  
if( !is_array( $content ) ) {
$content = file2array( $fname );
} else {
}
Else - пустое место? Сурово

Цитата:
Сообщение от None  
$bat = "@echo off\ncd thread0\n";
.....
file_put_contents( 'run.bat', $bat );
exec('run.bat');
unlink('run.bat')
Причем нигде не указано, что решение исключительно под win.

Цитата:
Сообщение от None  
function randel( $array ) {
return $array[ mt_rand( 0, count($array) - 1 ) ];
}
Ты не поверишь, но существует функция array_rand.

Цитата:
Сообщение от None  
function file2array( $filename ) {
$array = array();
foreach( file( $filename ) as $row ) if( $row = trim( $row ) ) {
$array []= $row;
}
return $array;
}
Опять модная функция. Неведомая проверка тоже радует, ТС, специально для тебя у функции file есть специальный флаг FILE_IGNORE_NEW_LINES.

[QUOTE="None"]
function array_rand_slice( $array, $amount ) {
shuffle( $array );
$sliced = array();
$step = floor( count( $array ) / $amount );
for( $i = 0; $i
 
Ответить с цитированием

  #3  
Старый 19.09.2010, 18:38
S0meT1me
Новичок
Регистрация: 02.06.2009
Сообщений: 20
С нами: 8916178

Репутация: 24
По умолчанию

Цитата:
Сообщение от Catbert  
И любой адекватный человек использует для этих целей другой язык программирования.
А ты загляни в топик продаж - таммного однопоточного софта на ПХП

Цитата:
Сообщение от Catbert  
Из-за скорости выполнения и нагрузки он и для работы с сетью с такими "потоками" не особо пригоден.
ты ещё скажи что для создания сайтов не пригоден

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

Цитата:
Сообщение от Catbert  
Ты не поверишь, но существует функция array_rand.
array_rand возвращает ключ, моя возвращает значение.

Цитата:
Сообщение от Catbert  
Бле, пересчет размера массива при каждой итерации...
PHP хеширует такие вещи

Цитата:
Сообщение от Catbert  
А тут в первой функции мы видим пересчет длины статической строки при каждом вызове. Не проще ли было воспользоваться функцией chr (например, chr(mt_rand(0x30, 127)))?
Проще с точки зрения скорости выполнения программы, но сложнее с точки зрения её читаемости

Цитата:
Сообщение от Catbert  
А во второй функции переменная $str вообще не инициализирована изначально.
Изначально она и так пуста/нул/ноль.

Цитата:
Сообщение от Catbert  
Ни в одной функции нет вообще никакой обработки ошибок. Даже если код где-то навернется, все равно продолжится его выполнение дальше. А навернуться тут очень много шансов.
Этот код работал уже годика полтора

З.Ы.: Catbert, чего так нервно? давно не трахался?

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

  #4  
Старый 19.09.2010, 19:24
Catbert
Познающий
Регистрация: 29.06.2010
Сообщений: 80
С нами: 8353046

Репутация: 10
По умолчанию

Цитата:
Сообщение от None  
А ты загляни в топик продаж - таммного однопоточного софта на ПХП
А в мире много безработных и нищих - это повод на них равняться?

Цитата:
Сообщение от None  
основные траты времени при работе сетевого приложения идут на запросы, так что интерпритируемый или компилируемый язык - это здесь не критично.
Правда? Т.е. ты утверждаешь что при работе с сетью пхп покажет скорость аналогичную программе написанной на с++ скажем?

Цитата:
Сообщение от None  
array_rand возвращает ключ, моя возвращает значение.
Т.е. лучше написать mt_rand( 0, count($array) - 1 , чем array_rand($array) ?

Ну да, конечно, лучше вызвать две функции чем одну.

$array[mt_rand( 0, count($array) - 1];

->

$array[array_rand($array)];

Цитата:
Сообщение от None  
PHP хеширует такие вещи
В ассоциативный массив заносит штоле?

Цитата:
Сообщение от None  
Этот код работал уже годика полтора
И Лада Калина может ездить полтора годика без поломки, однако она ни разу не пример качественного автомобилестроения.
 
Ответить с цитированием

  #5  
Старый 19.09.2010, 19:27
GRRRL Power
Постоянный
Регистрация: 13.07.2010
Сообщений: 823
С нами: 8332886

Репутация: 84


По умолчанию

Цитата:
Сообщение от S0meT1me  
А ты загляни в топик продаж - таммного однопоточного софта на ПХП
Все на пхп и пишут из-за того, что язык прост как зубочистка. А вы своей статьей провоцируете таких горе-кодеров не развиваться, изучая новые языки, а выжимать бесполезные вещи из всё того же php.

Цитата:
Сообщение от S0meT1me  
PHP хеширует такие вещи
Хеширует? Может быть, кеширует?

А вообще, я даже проверил это ради интереса. Ничего он там не кеширует.

PHP код:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]

[/
COLOR][/COLOR
Результаты:

Код:
Test 1: 0.170279979706
Test 2: 0.112259864807
Цитата:
Сообщение от S0meT1me  
Проще с точки зрения скорости выполнения программы, но сложнее с точки зрения её читаемости
А тут по-моему скорость важнее. А читаемость и так и так нормальна.

Цитата:
Сообщение от S0meT1me  
Изначально она и так пуста/нул/ноль.
Все же, она не пуста, она неопределена.

Цитата:
Сообщение от S0meT1me  
Этот код работал уже годика полтора
Коды во многих программах работают годика полтора, пока кто-то не находит в них уязвимость и разработчики не начинают паниковать. Ну это так, к слову.
 
Ответить с цитированием

  #6  
Старый 20.09.2010, 00:58
S0meT1me
Новичок
Регистрация: 02.06.2009
Сообщений: 20
С нами: 8916178

Репутация: 24
По умолчанию

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

Шутка, не дождётесь

Цитата:
Сообщение от None  
Правда? Т.е. ты утверждаешь что при работе с сетью пхп покажет скорость аналогичную программе написанной на с++ скажем?
Скорость будет сравнима, т.е. отличаться будет не в десятки и сотни раз, а возможно даже и не в разы.

Catbert, чего ты злой такой? и всё к мелочам приколупываешься?

Цитата:
Сообщение от None  
Все на пхп и пишут из-за того, что язык прост как зубочистка
Согласен, хотя и тут накодили такие вещи как CakePHP - довольно мощный фреймвёк.

Цитата:
Сообщение от None  
Хеширует? Может быть, кеширует?
Ну вот, мы друг-друга поняли

Цитата:
Сообщение от None  
Все же, она не пуста, она неопределена.
ну в рамках данного скрипта это приблизительно одно и то же, ну а если кодить строго и по канонам то да, ты прав.
 
Ответить с цитированием
Ответ



Предыдущая тема Следующая тема

Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.