
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]
Спасибо за внимание.
|
|
|
|
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|