2010-02-24 2 views
8

Я пытаюсь создать многопоточное приложение PHP прямо сейчас. Я прочитал много статей, в которых объясняется, как создавать многопоточность. Все эти примеры основаны на погружении процессов в разные рабочие файлы PHP. Actualy это также то, что я пытаюсь сделать, но есть проблема :)Многопоточность в PHP

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

Мы используют многосерверную среду в локальной сети для завершения процессов, поскольку процессы не связаны друг с другом или не разделяют одну и ту же память. Нам просто нужно их разжечь и позволить им работать в точное время. Каждый из процессов работает на 0,5 секунды, но у него есть возможность работать в течение 30 секунд.

Большинство примеров запускает PHP и ждет результатов. Но, к сожалению, в моей ситуации мне не нужно ожидать результата из потока. Мне просто нужно выполнить команду и записать результат в свою собственную базу данных.

Как я могу достичь, чтобы запустить phps и ждать, пока они будут работать на 10000 процессов?

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Я знаю, что PHP не имеет многопоточную функцию и не построен. Но мы должны создать способ его использования, например, мы можем отправить запрос на http://server1/dothis.php?jobid=5, но стандартные методы заставляют нас ждать результата. Если нам удастся отправить запрос на этот сервер, не дожидаясь результата, он решит нашу проблему, я думаю, или нам понадобится совершенно другой подход, такой как разделитель процессов с C++ или qt.

+3

вы не можете создать многопоточное приложение PHP. php не поддерживает потоковую обработку. – user187291

+1

Я не уверен в возможности вашей машины запускать 10000 одновременных потоков, но вам нужно рассмотреть адресное пространство, используемое вашими потоками. В Windows гранулярность распределения адресного пространства составляет 64 КБ, поэтому стек каждого потока занимает 64 Кбайт адресного пространства, даже если используется только 4 КБ. Таким образом, вы будете использовать пространство памяти 640 МБ для адресации в одиночку! – stillstanding

+1

Когда я вижу, что кто-то пытается использовать PHP для многопоточности, мне приходит в голову старая «если все, что у вас есть, это хаммер» –

ответ

6

Как указано, php не поддерживает многопоточность. Тем не менее, как упоминалось tomaszsobczczak, есть библиотека, которая позволит вам создавать «потоки» и оставлять их запущенными, а также повторно подключаться к ним через другие скрипты, чтобы проверить их статус и т. Д., Называемый «Gearman».

С главной страницы проекта: «Gearman предоставляет общую инфраструктуру приложения для работы на других машинах или процессах, которые лучше подходят для выполнения работы. Это позволяет вам работать параллельно, обрабатывать баланс нагрузки и для вызова функций между языками Он может использоваться в различных приложениях, начиная с веб-сайтов высокой доступности и транспорта событий репликации базы данных. Другими словами, именно нервная система связана с передачей распределенной обработки ».

Блог Rasmus имеет отличную запись об этом здесь: playing with gearman и для вашего случая это может быть просто решение, хотя я не читал никаких подробных тестовых примеров ... Было бы интересно узнать, хотя , поэтому, если вы закончите использовать это, сообщите об этом!

+0

Это будет решение, я думаю, спасибо вам как tomaszsobczak ant danp :) –

+1

Прошу прощения за этот tooooo поздний ответ, но это ответ разрешило нашу проблему :) Еще раз спасибо tomaszsobczak и danp :) –

3

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

Вот то, однако:

Код для фона исполнения

<?php 
function execInBackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
     pclose(popen("start /B ". $cmd, "r")); 
    } 
    else { 
     exec($cmd . " > /dev/null &"); 
    } 
} 
?> 

Найдено в http://php.net/manual/en/function.exec.php#86329

+0

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

5

Как говорят комментарии, многопоточность не представляется возможным в PHP. Но, основываясь на ваш комментарий:

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

Вы можете запустить PHP скрипт для запуска в фоновом режиме используя exec(), перенаправляя вывод сценария где-то в другом месте (например, /dev/null). Я думаю, это лучшее, что вы получите. Из инструкции по эксплуатации:

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

В Комментариях, внесенных пользователем, имеется несколько заметок и указателей, например this snippet, что позволяет выполнять фоновое выполнение как на платформах Windows, так и на Linux.

Конечно, этот скрипт PHP не будет передавать состояние или любые данные скрипта PHP, который вы используете. Вам придется инициализировать фоновый скрипт, как если бы вы делали совершенно новый запрос.

+0

Итак, если скрипт позволяет сказать, что a.php запускает exec ('... b.php> .../log1.txt', ...); и b.php выполняет выполнение в течение 20 секунд, а a.php заканчивается через 1 сек. B.php все еще работает над выполнением или a.php ждет b? Если он ждет b, как он может выполнять другого рабочего, например c.php, в среднем? –

+0

@Harun a.php не будет ждать b.php. a.php может выполнять столько рабочих, сколько захочет, повторяя процедуру exec(). –

+0

еще раз спасибо Pekka, я также попытаюсь построить свое решение на этом. –

2

Вы действительно хотите иметь многопоточность в php?

Или вы просто хотите выполнить скрипт php каждую секунду? В последнем случае достаточно одного кропольного подхода «выполнить этот файл каждую секунду» с помощью консольных инструментов linux.

+0

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

1

Если ваша задача состоит в том, чтобы сделать много HTTP-запросов, вы можете использовать curl multi. Существует хорошая библиотека для делать это: http://code.google.com/p/rolling-curl/

+0

Я посмотрел на CURL multi, но некоторые говорят, что на самом деле возникают большие накладные расходы, когда он используется для большого количества URL-адресов. В дополнение к этому нам не нужно видеть результат. Если выполнение проходит время выполнения, это также информация для нас, что выполнение не может завершиться успешно. –

1

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

Тем не менее, вы слышали Facebook PHP Compiler? В основном он компилирует ваш PHP для высоко оптимизированного C++ и использует g ++ для его компиляции. Это открывает мир возможностей, включая, но не ограничиваясь, многопоточность!

Проект с открытым исходным кодом и его на github

+0

Я знаю это, это фантастическая работа, на которую я смотрел возрасты :) Но, как мы думаем со стороны наших разработчиков, было бы очень сложно объяснить это им в этой ситуации, но, опять же, мы будем искать это как альтернатива :) –

1

, если вы просто хотите отправить запрос HTTP, просто сделать это с помощью PHP CURL LIB. Это решит вашу проблему.

Смежные вопросы