Вопрос

я нашел это Пакет PECL под названием threads, но релиза еще нет.И на сайте PHP ничего не появляется.

Это было полезно?

Решение

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

Другие советы

Из руководства PHP для pthreads расширение:

pthreads — это объектно-ориентированный API, который позволяет пользователю выполнять многопоточность в PHP.Он включает в себя все инструменты, необходимые для создания многопоточных приложений, предназначенных для Интернета или консоли.Приложения PHP могут создавать, читать, записывать, выполнять и синхронизировать с потоками, рабочими и стековыми объектами.

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

Первый выпуск PHP4, выпущенный 22 мая 2000 г., PHP был выпущен с потокобезопасной архитектурой - способом выполнения нескольких экземпляров своего интерпретатора в отдельных потоках в многопоточных средах SAPI (Server API).За последние 13 лет дизайн этой архитектуры сохранялся и совершенствовался:С тех пор он используется на крупнейших веб-сайтах мира.

Потоковая обработка пользовательской среды никогда не была проблемой для команды PHP и остается таковой по сей день.Вы должны понимать, что в мире, где работает PHP, уже существует определенный метод масштабирования — добавление оборудования.За многие годы существования PHP аппаратное обеспечение становилось все дешевле и дешевле, и поэтому это все меньше и меньше беспокоило команду PHP.Хотя он становился дешевле, он также стал намного мощнее;сегодня наши мобильные телефоны и планшеты имеют двух- и четырехъядерную архитектуру и достаточно оперативной памяти, наши настольные компьютеры и серверы обычно имеют 8 или 16 ядер, 16 и 32 гигабайта оперативной памяти, хотя мы не всегда можем иметь два в рамках бюджета и наличие двух рабочих столов редко бывает полезным для большинства из нас.

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

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

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

Для тех, кто желает изучить его, pthreads предоставляет API, который позволяет пользователю выполнять многопоточные PHP-приложения.Этот API находится в стадии разработки и имеет бета-уровень стабильности и полноты.

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

pthreads использует потоки Posix (даже в Windows), то, что создает программист, является реальными потоками выполнения, но для того, чтобы эти потоки были полезными, они должны знать PHP - уметь выполнять пользовательский код, совместно использовать переменные и предоставлять полезные средства связи. (синхронизация).Таким образом, каждый поток создается с экземпляром интерпретатора, но по задумке его интерпретатор изолирован от всех других экземпляров интерпретатора - точно так же, как многопоточные среды API сервера.pthreads пытается преодолеть этот разрыв разумным и безопасным способом.Многие из проблем программиста потоков на C просто не волнуют программиста pthreads, по задумке pthreads копирует при чтении и копирует при записи (оперативная память дешева), поэтому никакие два экземпляра никогда не манипулируют одними и теми же физическими данными. , но они оба могут повлиять на данные в другом потоке.Тот факт, что PHP может использовать функции безопасности потоков в своем базовом программировании, совершенно не имеет значения: пользовательские потоки и его операции полностью безопасны.

Зачем копировать при чтении и копировать при записи:

public function run() {
    ...
    (1) $this->data = $data;
    ...
    (2) $this->other = someOperation($this->data);
    ...
}

(3) echo preg_match($pattern, $replace, $thread->data);

(1) Пока в хранилище данных объекта pthreads удерживается блокировка чтения и записи, данные копируются из исходного местоположения в памяти в хранилище объектов.pthreads не корректирует счетчик ссылок переменной, Zend может освободить исходные данные, если на них больше нет ссылок.

(2) Аргумент someOperation ссылается на хранилище объектов, сохраненные исходные данные, которые сами являются копией результата (1), снова копируются для движка в контейнер zval, при этом сохраняется блокировка чтения. хранилище объектов, блокировка снимается и движок может выполнить функцию.Когда создается zval, его счетчик ссылок равен 0, что позволяет движку освободить копию после завершения операции, поскольку других ссылок на нее не существует.

(3) Последний аргумент preg_match ссылается на хранилище данных, получается блокировка чтения, набор данных в (1) копируется в zval, снова с счетчиком ссылок 0.Блокировка снимается. Вызов preg_match работает с копией данных, которая сама по себе является копией исходных данных.

Что нужно знать:

  • Хэш-таблица хранилища объектов, в которой хранятся данные, является потокобезопасной.
    на основе TsHashTable, поставляемого с PHP, от Zend.

  • Хранилище объектов имеет блокировку чтения и записи, для TsHashTable предусмотрена дополнительная блокировка доступа, так что, если требуется (а это так, var_dump/print_r, прямой доступ к свойствам, поскольку движок PHP хочет ссылаться на них), pthreads может манипулировать TsHashTable за пределами определенного API.

  • Блокировки удерживаются только во время операций копирования. Когда копии сделаны, блокировки снимаются в разумном порядке.

Это означает:

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

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

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

Это не общая архитектура, и единственный способ существования — сосуществовать.Те, кто немного сообразителен, увидят, что здесь происходит много копирования, и зададутся вопросом, хорошо ли это.В динамической среде выполнения происходит довольно много копирования, это динамика динамического языка.pthreads реализован на уровне объекта, поскольку хороший контроль можно получить над одним объектом, но методы — код, который выполняет программист — имеют другой контекст, свободный от блокировок и копий — локальную область действия метода.Область объекта в случае объекта pthreads следует рассматривать как способ обмена данными между контекстами, в этом и заключается его цель.Имея это в виду, вы можете использовать методы, позволяющие избежать блокировки хранилища объектов, если в этом нет необходимости, например, передавать переменные локальной области другим методам в многопоточном объекте вместо того, чтобы копировать их из хранилища объектов при выполнении.

Большинство библиотек и расширений, доступных для PHP, представляют собой тонкие оболочки сторонних разработчиков, основная функциональность PHP в некоторой степени аналогична.pthreads — это не тонкая оболочка Posix Threads;это API потоковой обработки, основанный на Posix Threads.Нет смысла реализовывать потоки в PHP, которые пользователи не понимают или не могут использовать.Нет никаких причин, по которым человек, не знающий, что такое мьютекс или что он делает, не сможет воспользоваться всем, что у него есть, как с точки зрения навыков, так и с точки зрения ресурсов.Объект функционирует как объект, но там, где в противном случае два контекста столкнулись бы, pthreads обеспечивает стабильность и безопасность.

Любой, кто работал в Java, увидит сходство между объектом pthreads и потоками в Java. Те же самые люди, несомненно, увидят ошибку под названием ConcurrentModificationException - поскольку это звучит как ошибка, возникающая во время выполнения Java, если два потока записывают одни и те же физические данные. одновременно.Я понимаю, почему он существует, но меня сбивает с толку тот факт, что при столь дешевых ресурсах в сочетании с тем фактом, что среда выполнения может обнаружить параллелизм в тот точный и единственный момент, когда может быть достигнута безопасность для пользователя, который он решает выдавать потенциально фатальную ошибку во время выполнения, а не управлять выполнением и доступом к данным.

Pthreads не будет выдавать таких глупых ошибок, я считаю, что API написан так, чтобы сделать многопоточность максимально стабильной и совместимой.

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

Наконец, из руководства PHP:

pthreads был и остается экспериментом с довольно хорошими результатами.Любые из его ограничений или функций могут измениться в любое время;такова природа экспериментирования.Его ограничения, часто налагаемые реализацией, существуют по уважительной причине;Цель pthreads — предоставить полезное решение для многозадачности в PHP на любом уровне.В среде, в которой выполняются pthreads, необходимы некоторые ограничения и ограничения для обеспечения стабильной среды.

Вот пример того, что предложил Вилко:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);

По сути, это выполняет сценарий PHP в командной строке, но сразу же возвращает PID, а затем запускается в фоновом режиме.(Эхо $!гарантирует, что ничего больше не будет возвращено, кроме PID.) Это позволит вашему PHP-скрипту продолжить работу или завершить работу, если вы этого захотите.Когда я использовал это, я перенаправлял пользователя на другую страницу, где каждые 5–60 секунд выполняется вызов AJAX, чтобы проверить, выполняется ли отчет.(У меня есть таблица для хранения gen_id и пользователя, с которым он связан.) Сценарий проверки выполняет следующее:

exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
     // less than 2 rows in the ps, therefore report is complete
}

Здесь есть небольшой пост об этой технике: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

Суммируя:да, в PHP есть многопоточность, но вместо этого вам следует использовать многопоточность.

Справочная информация:нити против.процессы

Всегда возникает некоторая путаница в различении потоков и процессов, поэтому я кратко опишу оба:

  • А нить представляет собой последовательность команд, которые будет обрабатывать процессор.Единственные данные, из которых он состоит, — это счетчик программ.Каждое ядро ​​ЦП будет обрабатывать только один поток за раз, но может переключаться между выполнением разных потоков посредством планирования.
  • А процесс представляет собой набор общих ресурсов.Это означает, что он состоит из части памяти, переменных, экземпляров объектов, дескрипторов файлов, мьютексов, подключений к базе данных и так далее.Каждый процесс также содержит один или несколько потоков.Все потоки одного и того же процесса совместно используют свои ресурсы, поэтому вы можете использовать в одном потоке переменную, созданную вами в другом.Если эти потоки являются частями двух разных процессов, они не могут напрямую обращаться к ресурсам друг друга.В этом случае вам нужно межпроцессного взаимодействия через, напримерканалы, файлы, сокеты...

Многопроцессорность

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

В php у вас есть два способа создать новый процесс:

пусть ОС сделает это за вас:вы можете указать своей операционной системе создать новый процесс и запустить в нем новый (или тот же) PHP-скрипт.

  • для Linux вы можете использовать следующее или рассмотреть Ответ Дэррила Хейна:

    $cmd = 'nice php script.php 2>&1 & echo $!';
    pclose(popen($cmd, 'r'));
    
  • для окна вы можете использовать это:

    $cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"';
    pclose(popen($cmd, 'r'));
    

сделай это сам с помощью вилки:php также предоставляет возможность использовать разветвление через функцию pcntl_fork().Хороший учебник о том, как это сделать, можно найти здесь но я настоятельно рекомендую не использовать его, так как форк - преступление против человечества и особенно против опа.

Многопоточность

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

Стандартный PHP не обеспечивает многопоточность, но есть (экспериментальное) расширение, которое действительно это делает: pthreads.Его API-документация даже вошла в php.net.С его помощью вы можете делать некоторые вещи, как вы можете в настоящие языки программирования :-) так:

class MyThread extends Thread {
    public function run(){
        //do something time consuming
    }
}

$t = new MyThread();
if($t->start()){
    while($t->isRunning()){
        echo ".";
        usleep(100);
    }
    $t->join();
}

Для Linux есть инструкция по установке прямо здесь, в stackoverflow.

Для окна сейчас есть такой:

  • Сначала вам нужна потокобезопасная версия php.
  • Вам нужны предварительно скомпилированные версии pthreads и его расширения php.Их можно скачать здесь.Убедитесь, что вы загружаете версию, совместимую с вашей версией PHP.
  • Скопируйте php_pthreads.dll (из только что загруженного zip-архива) в папку расширения PHP ([phpDirectory]/ext).
  • Скопируйте pthreadVC2.dll в [phpDirectory] (корневую папку, а не папку расширения).
  • Отредактируйте [phpDirectory]/php.ini и вставьте следующую строку

    extension=php_pthreads.dll
    
  • Проверьте это с помощью приведенного выше сценария, немного поспав или что-нибудь прямо там, где находится комментарий.

И теперь большой НО:Хотя это действительно работает, PHP изначально не был создан для многопоточности.Существует поточно-ориентированная версия php, и, начиная с версии 5.4, она почти не содержит ошибок, но использование php в многопоточной среде по-прежнему остается невозможным. не рекомендуется в руководстве по PHP (но, возможно, они просто еще не обновили свое руководство по этому поводу).Гораздо большей проблемой может быть то, что много общих расширения не являются потокобезопасными.Таким образом, вы можете получать потоки с этим расширением php, но функции, от которых вы зависите, по-прежнему не являются потокобезопасными, поэтому вы, вероятно, столкнетесь с условиями гонки, взаимоблокировками и т. д. в коде, который вы не писали сами...

Вы можете использовать pcntl_fork() чтобы добиться чего-то похожего на потоки.Технически это отдельные процессы, поэтому связь между ними не так проста с помощью потоков, и я считаю, что это не будет работать, если PHP вызывается Apache.

Если кому интересно, я воскрес. php_threading (не то же самое, что потоки, но похоже), и у меня это действительно работает до такой степени, что работает (в некоторой степени) хорошо!

Страница проекта

Скачать (для Windows PHP 5.3 VC9 TS)

Примеры

ПРОЧТИ МЕНЯ

pcntl_fork() это то, что вы ищете, но это разветвление процесса, а не поточность.поэтому у вас возникнет проблема обмена данными.для их решения вы можете использовать функции семафора phps ( http://www.php.net/manual/de/ref.sem.php ) очереди сообщений могут быть немного проще для начала, чем сегменты общей памяти.

В любом случае, стратегия, которую я использую в разрабатываемой мной веб-инфраструктуре, которая параллельно загружает ресурсоемкие блоки веб-страницы (вероятно, с внешними запросами):я создаю очередь заданий, чтобы узнать, какие данные я жду, а затем распределяю задания для каждого процесса.после завершения они сохраняют свои данные в кэше APC под уникальным ключом, к которому может получить доступ родительский процесс.как только все данные есть, это продолжается.я использую простой usleep() ждать, потому что в Apache невозможно взаимодействие между процессами (дети потеряют связь со своими родителями и станут зомби...).Итак, это подводит меня к последнему:важно убить каждого ребенка!есть также классы, которые разветвляют процессы, но сохраняют данные, я не исследовал их, но в Zend Framework есть один, и они обычно пишут медленный, но надежный код.Вы можете найти это здесь:http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.htmlя думаю, они используют сегменты shm!ну и последнее, но не менее важное: на этом сайте Zend есть ошибка, незначительная ошибка в примере.

while ($process1->isRunning() && $process2->isRunning()) {
    sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
    sleep(1);
}

На основе PThreads активно разрабатывается расширение Threading, которое выглядит очень многообещающе. https://github.com/krakjoe/pthreads

Просто обновление, похоже, что ребята из PHP работают над поддержкой потока, и он уже доступен.

Вот ссылка на него:http://php.net/manual/en/book.pthreads.php

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

РЕДАКТИРОВАТЬ:Теперь она доступна как библиотека композиторов и как часть моей структуры MVC Hazaar MVC.

Видеть: https://git.hazaarlabs.com/hazaar/hazaar-thread

Я знаю, что это старый вопрос, но вы можете посмотреть http://phpthreadlib.sourceforge.net/

Двунаправленная связь, поддержка Win32 и отсутствие необходимости в расширениях.

Когда-либо слышал о appserver из техподразделения?

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

Существует довольно малоизвестная функция, которая вскоре будет признана устаревшей, под названием клещи.Единственное, для чего я когда-либо использовал его, это позволить сценарию перехватить SIGKILL (Ctrl+C) и корректно закрыться.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top