Как стать автором
Обновить

Комментарии 78

error_reporting E_ALL поставьте плиз
и код подчистите, если не трудно
а то строки типа

public function wait() {return pcntl_wait($status);}

где $status это неизвестно что, странно смотрятся
Поставил. wait() исправил. Спасибо.
А как у вас с мьютексами?
И с дэдлоками:)
Хотя, как я понял, это эмуляция потоков процессами, следовательно общей памяти нет.
Чтобы полностью эмулировать потоки, в килобайт кода думаю не уложиться:)
Кстати, для PHP есть еще порт pthreads.
Mutex'ы уже в стадии тестирования.
Разделяемая память через sem.
Посмотрел sem, и мьютексы через него же делаете?
Забавная вещь получается, покрайней мере интерфейсно — один в один как Java:)

Мне вот еще интересно, а какой алгоритм помещения переменных в shared mem?
Просто при запуске все глобальные?
Ведь я правильно понял, что sem просто предоставляет буфер для обмена данными в виде ключ/значение?

Тогда будут проблемы с синхронизацией значений переменных, или в shm_put_var значение передается по ссылке?

Кстати, там в комментах пишут:
«shm_put_var has no protection against race conditions. If two scripts insert the same key at the same time php might segfault» — такое тоже придется отлавливать.

И еще, я же могу динамически во время исполнения переопределять функции?(PHP я почти не знаю, вот и спрашиваю:))
То есть что то типо eval("function a(){}"); притом, что `a` уже определена.
Если я сделаю так в одном потоке, нужно автоматически сделать тоже в других(переопределить eval?:)).
Ну только учитывая контекст естественно.
Да, через него же.
> И еще, я же могу динамически во время исполнения переопределять функции?(
Увы, нет.
и слава богу!
не нравится фраза — буквально на коленке — страшно юзать :(
в своем коде багов хватает, а еще и чужой коленочный отлаживать, увольте…
Вы уволены :).
Вот-вот, уже ведь есть велосипед, зачем ещё один?
чтобы соревнования устраивать!
Это ж не потоки, а процессы. И «вы» опять с большой буквы, сколько ж можно!
Да, процессы.
С большой, и что? По правилам русского языка надо писать с большой, при уважительном обращении к одному человеку, а не к группе лиц. В данном случае я обращаюсь к своему читателю.
В данном случае вы обращаетесь к группе лиц: к своим читателям. К какому конкретно читателю вы обращаетесь? Ко мне? «Вы» пишется с большой, когда можно вместо него конкретное имя поставить.
В общем, «вы» всегда можно писать с маленькой, поскольку обращение на «вы» уже само по себе является уважительным отношением к собеседнику.
Если это процессы, то зачем вы вводите людей в заблуждение? Вы не знаете чем потоки от процессов отличаются?
bolk в данном случае прав, однако данный спор здесь совершенно не к месту.
Да я заколебался уже. Все как будто вокруг маркетологами стали. Скоро ещё и большими буквами будут писать, с восклицательными знаками после каждого слова.
холиварщики.
Холивар — это если бы мы решали что лучше.

А так я просто говорю о том, что эта штука называется иначе.
да я про ВЫ не вы, лингвистический форум =)
Какой может быть холивар, если есть чётко прописанные правила?
кстати про потоки и процессы на уровне логики вы делаете разделение? лично я редко, очень редко
Не понял вопроса.
ну для вас в понимании работы системы важно это разделение?
Смотря на каком уровне я работаю. В PHP это разделение важно. Так как для тредов нужен thread safe PHP, а его даже в пакеты не собирают.

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

И так далее и тому подобное.
Сэмулировать можно все что угодно. А вот код ради кода смысл мало имеет.

Пожалуйста, напишите когда и где это может быть с успехом использовано, причем все плюсы и минусы по сравнению с другими методами. Тогда кое что… А пока это «Пацаны приколитись, как я умею!». Извините за сарказм.
Спасибо, напишу дополнение. Да, сарказм, Imho, мимо кассы.
Артём, каким другими? В PHP больше ничего нет для многозадачности, кроме процессов. Разве что выше дали ссылку на порт pthreads, но там явно нужен TS PHP, а с ним некоторые модули не пашут.
Ну про «эмуляцию» многопоточности на php писали очень много. Например, в качестве «другого» метода может быть непосредственный вызов скрипта в фоновом режиме с отправкой вывода в dev/null. Чем не эмуляция? Да, я знаю что это намного хуже но работает много где, в отличие от pcntl который далеко не на каждом хостинге установлен.
Это уже не многопроточность в PHP, а многопоточность в OS.
А чем это плохо? Поясните, будьте добры.
Я долго смотрел на коментарий выше, но не понял где написано что «это плохо». Просто обращалось внимание, что это немного другое.

Единственное к чему можно придраться это «многопоточность в OS», хотя по смыслу тут более подходит «многозадачность в OS».
логика просто другая. более сложный обмен сообщениями, да все по-другому.
Интересно было бы узнать, где это можно применить?
Я сделал дополнение в конце.
В тот момент когда читал не было — спасибо.
Имхо первый пример не убедительный. Если данные ещё в процессе получения, что отрисовываться будет? Разве что вспомогательные данные, но тогда это не стоит оптимизировать.
Допустим, мы строим ломаную, вершины которой считаются в соответствие с результатами запроса. Мы можем начать рисовать еще до того как пришли все ряды.
краулеры, демоны, прекешеры, и прочий адский сброд
например сбор рекламных объявлений с множества фидов
имхо, критически не хватает join и возврата результата с функции. или я плохо смотрел код? все это дело в больших объемах может очень не хило подгрузить сервак, потом что process switch намного тяжелее thread switch
И где же тут shared state?
Дай пример с общими переменными в обоих потоках.
Вы не делаи. Но это был провокационный вопрос, так как в коде этого нету. И намека на это.
Так что в следующий раз когда попытаетесь наврать — не врите.

Вы не написали реализацию нитей.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Я, конечно, боюсь показаться неоригинальным, — но я думаю, что выскажу мысль, которая терзала многих, читаемых этот топик — зачем извращаться, когда есть хотя бы Perl, к примеру?:) Где всё это делается двумя строчками грубо говоря:

my $pid = fork;
doAct() if $pid == 0;

— если говорить про нормальную многопоточность.

И треды те же там тоже есть.)

С этим не получится нормального многопоточного и эффективного приложения, правда! C PHP — что многопоточность, что какой-либо серьёзный хайлоад — баловство всё это, а если не баловство — то с обязательными обвесами типа акцелератора или ещё какой-нибудь богомерзкой софтины.

Я уже чувствую минусы и злобную ненависть — ну чесслово, давайте использовать вещи по назначению :) Это уже не первый топик про попытки многопоточности в PHP — и все предыдущие тоже не несли в себе ничего хорошего — сначала народ холиворил — теперь видимо притомился обьяснять что-то:)
А чем Вам не нравится кеширование byte-кода eAccelerator'ом?
По поводу highload'а и PHP… Вы знаете на чем написан vkontakte?
не может быть)
X-Powered-By: PHP/5.2.0-8+etch13

как и масса других сайтов. Опять же — какой-нибудь акцелератор там стоит, — и веб крутится на nginx.
Кроме того — одно дело писать простецкие быстро отрабатывающие вещи — три притопа, два прихлопа, пять запросов к БД — и совсем другое — писать что-то, что делает реально тяжёлые вещи.

под highload я бОльшей частью имел то, что относится к многопоточности и не веб-программам всё же.
а никто в здравом уме не «для веба» на PHP писать и не будет, есть для этого упомянутый Perl. Т.е. вы абсолютно правы, но например писать сайты на PHP как раз лучше. Золотых пуль нет и подход описанный в статье тоже может быть полезен.
Чьёрт побьери, Кэп! :)
Это не многопоточность, а многозадачность.

Тот же самый код на PHP выглядит вот так:

$pid = pcntl_fork();
if (!$pid) doAct();
А, спасибо, да.
Тем не менее, я всё равно остаюсь при своём :)
Раз уж вы «рады любым отзывам, идеям и замечаниям», то позволю еще чуть-чуть докапаться. :-)

> 1. Когда программа недостаточно быстро получает данные и растёт время простоя. Например,
> при генерации красивого графика можно одним потоком получать данные из СУБД
> (выполняется тяжелый запрос), а во втором потоке производить отрисовку.

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

> 2. Когда нужно выполнить несколько операционных задач, и более эффективно
> задействовать процессор.

Еще б уточнить, что это за «операционные задачи» и тогда вообще все шоколадно. Более эффективно задействовать процессор тоже хорошо, но к сожалению не всегда реализуемо, ибо время работы процессора в большинстве случаев крайне ничтожно, а основное время работы — это опреции ввода-вывода.

А теперь действительно ГДЕ это может быть примерено и почему.

1. В создании «демонов» на php. Изредка приходится с этим сталкиваться, пример тому различные обработки очередей, сервисы типа flashpolicyd, обслуж.ивание сайтов (например очистка кеша при излишнем его разрастании и др.). Воббще, демон часто способен решить задачи, которые простые скрипты будут решать менее эффективно. А без pcntl демона нормально не напишешь.

2. При задачах, где требуется одновременно обработать большое количество однотипных объектов, которые обрабатываются достаточно долго. Например, рассылка писем, поисковая индексация, «сбор» RSS-лент и др. С графиками тут тоже пример хороший: если надо сделать этак десятка два сразу, то можно при генерации страницы запустить постройку этих графиков и отрендерить страницу. Пока страница дойдет до клиента, браузер её отрендерит и сделает запрос по ссылкам на эти самые графики, то они будут уже построены. Можно легко обойтись и без pcntl, но это действительно будет менее эффективно.

3. В случаях, когда требуется выполнить действитя, котоыре занимают достаточно продолжительное время, но не влияют на результат. Напрмер, копирование больших файлов, которые загрузил пользователь или работа с большими изображениями и т.д. Тогда в одном процессе можно генерить страницу дальше, а другом запустить обработку, благо нам не нужен результат от неё немедленно. Опять же: можно обойтись и без pcntl, но будет хуже.

Вот как-то так. Со всеми этими случаями сталкивался лично на практике, и распараллеливание приносило хорошие результаты
1. Смотря какие графики.
2. Анализ текста к примеру.

1. Ага, я писал dns-сервер на PHP, работает просто замечательно в плане производительности.
2. Это я изложил в первом пункте.
3. А вот это не надо. В таких случаях надо делать отдельную очередь задач и облако воркеров.
Пожалуйста, поясните про «отдельную очередь задач и облако воркеров». Я немного не понял, что имелось ввиду и как это может быть реализовано.
Охотно.
Теория: Запускается нужное количество процессов-воркеров, можно даже сделать master, который будет spawn'ить их дополнительно при необходимости, и убивать idle. Все эти процессы имеют одинаковый приоритет и смотрят в очередь задач, при этом одна задача из очереди гарантированно падает лишь к одному воркеру.
Практика: habrahabr.ru/blogs/php/59982/ там есть примеры Queue и MapReduce.
полноценный продакшн flashpolicyd на эрланге ~100 строк )
1.
2. И ещё, эффективно задействовать процессор — настолько не тривиальная задача, что иногда проще реорганизовать обработку данных, чем решать что с чем может паралельно выполняться.

1. Можно, а можно и так:
* Обработка очередей делается через запуск необходимого количества обработчиков по крону. Разделение обрабатываемых задач происходит по пессимистической блокировке или делением идентификаторов задач на чётные и нечетные (в случае двух обработчиков).
* Сервисы (типа DNS) реализуются с помощью xinit.d и общего кеша.
2. Согласен
3. Согласен
1) Процессы != потоки
2) Я бы советовал с осторожностью плодить процессы, находясь в контексте веб-сервера. Апач у меня при подобных экспериментах дох на раз.

Согласен, но изменить реализацию можно без смены API.
«Параллельные вычисления — технология будущего… и так будет всегда»
Мильен баксов и респект человеку который всунет OpenMP в пхп!!!
Остальное от лукавого :)
Недавно, сильно уважаемый мной, smira расказывал про деферед подход, который по сути есть вариация на тему OpenMP
(пс: OpenMP это не только библиотека, но также и идеология, поход и… патч к компилятору :) )
в пхп пока что даже threads без костылей нет, какой уж тут OpenMP :) а если помечтать, то например аналог PLINQ был бы тут очень полезен
я как человек, который учился в универе писать на OpenMP и MPI ненавижу их лютой ненавистью =) и есть тому причины, не считаю уместным рссказывать тут весь личный опыт, но результат такой: подход принятый в JAVA мне очень симпатичен
подход JAVA и компании хорош для распараллеливания логики, модулей и других ентити что просто работают параллельно, и мне он тоже очень нравиться.

Если вы захотите распаралеть банальное вычисление в цикле, обход дерева и тд и тп — вы сдохнете :)
А OpenMP это все же в большей мере патч в компилятор
… хотя… указный мною пример наверное сдохнет на клиентских приложениях от одного запаха CUDA, но на серверных решениях — самое то :)

А вообще не время еще параллельной обработки информации — вот когда не надо будет думать сколько у тебя ядер, и сколько можно раз форкнуться чтобы нормально все работало — тогда да
( все не выходит у меня из головы плакат в комнате геймдевелоперов для PS3, где было расписано что у них на каком проце висит — потому как выходить за этот предел нельзя — тормозить будет, но и меньше лучше не использовать — играться будет не так красиво)
а зачем в языке заточеном под веб многопоточность?
семафоры как-то реализованы?
Интересно, автору спасибо)
Хорошее начало. Буду следить за развитием.
Спасибо, как раз и попробую в одном проекте :).
Нужно выкачивать из стороннего сервера-поставщика много различной информации (фотографии, xml-файлы), связь нередко обрывается, а одним потоком скачивать — жуть.
Для «многопоточного» выкачивания есть ru.php.net/manual/en/function.curl-multi-init.php, или даже ru.php.net/socket_select. Это намного проще и быстрее (плюс — не имеет ни какого отношения к многопоточности :) ).
Быстрее? Сомневаюсь.
Сомневаюсь

с опытом это пройдет. =)
Как раз сомнение — это как раз признак опыта. «Чем меньше знаешь, тем больше сомневаешься.»
:-) Опечатался «Чем меньше знаешь, тем меньше сомневаешься.»
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории