 |

19.09.2010, 15:32
|
|
Новичок
Регистрация: 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]
Спасибо за внимание.
|
|
|

19.09.2010, 16:57
|
|
Познающий
Регистрация: 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
|
|
|

19.09.2010, 18:38
|
|
Новичок
Регистрация: 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: я не претендую на звание мега-кул программера и знаю свой уровень, если где допускаю ошибку - можно просто сказать, без понтов училки-задротки. и писал этот топик не для того что бы показать какой я крутой задрот, а что бы помочь кому-то
|
|
|

19.09.2010, 19:24
|
|
Познающий
Регистрация: 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
Этот код работал уже годика полтора
И Лада Калина может ездить полтора годика без поломки, однако она ни разу не пример качественного автомобилестроения.
|
|
|

19.09.2010, 19:27
|
|
Постоянный
Регистрация: 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
Этот код работал уже годика полтора
Коды во многих программах работают годика полтора, пока кто-то не находит в них уязвимость и разработчики не начинают паниковать. Ну это так, к слову.
|
|
|

20.09.2010, 00:58
|
|
Новичок
Регистрация: 02.06.2009
Сообщений: 20
С нами:
8916178
Репутация:
24
|
|
Ох вы и злые... я ж не софт для запуска шатла писал, всё к словам да мелочам придираетесь. Уйду я от вас
Шутка, не дождётесь
Сообщение от None
Правда? Т.е. ты утверждаешь что при работе с сетью пхп покажет скорость аналогичную программе написанной на с++ скажем?
Скорость будет сравнима, т.е. отличаться будет не в десятки и сотни раз, а возможно даже и не в разы.
Catbert, чего ты злой такой? и всё к мелочам приколупываешься?
Сообщение от None
Все на пхп и пишут из-за того, что язык прост как зубочистка
Согласен, хотя и тут накодили такие вещи как CakePHP - довольно мощный фреймвёк.
Сообщение от None
Хеширует? Может быть, кеширует?
Ну вот, мы друг-друга поняли
Сообщение от None
Все же, она не пуста, она неопределена.
ну в рамках данного скрипта это приблизительно одно и то же, ну а если кодить строго и по канонам то да, ты прав.
|
|
|
|
 |
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|