Введение

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

Подсказка

Попробуйте вместо этого использовать parallel.

Внимание

Это расширение доступно только для CLI-приложений. Исходя из этого, многопоточность в PHP в окружении веб-сервера недоступна.

Внимание

pthreads (v3) может использоваться только с PHP 7.2 и выше, так как ZTS-режим нестабилен в 7.0 и 7.1.

Класс Threaded предоставляет базовый функционал, необходимый для работы pthreads. Он предоставляет методы синхронизации и некоторые полезные для разработчика интерфейсы.

Класс Thread позволяет создавать потоки. Для создания потока необходимо создать наследующие его класс и в нём реализовать метод run. Любые свойства могут быть записаны и прочитаны из любого контекста через ссылку на поток. Также из любого контекста могут быть вызваны публичные и защищенные методы. Метод run будет запущен в отдельном потоке, как только будет вызван метод Thread::start() из контекста, в котором он был создан. Стартовать и присоединить поток можно только в том контексте, где он был создан.

Класс Worker имеет постоянное состояние и будет доступен из метода Thread::start() (унаследованный метод) до тех пор, пока объект не выйдет из области видимости, либо пока не будет принудительно остановлен (с помощью Worker::shutdown()). Любой контекст имеющий ссылку к данному объекту может добавлять задания на стек Worker (с помощью Worker::stack()), которые будут запущены в отдельном потоке. Метод run объекта Worker будет запущен раньше, чем любой объект с его стека задач, что дает возможность инициализировать необходимые для задачи ресурсы.

Класс Pool используется для создания группы исполнителей (worker) для распределения между ними объектов Threaded. Это самый простой и эффективный вариант использования многопоточности в PHP.

Предостережение

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

Класс Volatile добавлен в pthreads v3. Он используется для задания изменяемых Threaded-свойств классов типа Threaded (так как теперь они по умолчанию неизменяемы). Также используется для хранения массивов PHP в контексте Threaded.

Синхронизация - важная часть многопоточности. Все объекты, созданные pthreads, имеют встроенные методы для обеспечения синхронизации (они покажутся очень знакомыми для разработчиков на Java): Threaded::wait() и Threaded::notify(). Вызов Threaded::wait() переведет объект в ожидание до того момента, пока из другого контекста не будет вызван Threaded::notify() для ожидающего объекта. Этот механизм позволяет осуществлять синхронизацию между объектами Threaded.

Предостережение

Любые объекты вашего приложения, которые предполагается использовать в многопоточном режиме, должны наследовать Threaded.

Хранение данных: Как правило, в объекте Threaded можно использовать любые данные, которые могут быть сериализованы. Они могут быть записаны и прочтены из любого контекста через ссылку на этот объект. Не каждый тип данных хранится в сериализованном виде. Базовые типы хранятся в их истинной форме. Сложные типы, массивы и объекты , не являющиеся Threaded, хранятся сериализованными; они могут быть прочитаны или записаны в Threaded-объект из любого контекста по ссылке. За исключением Threaded-объектов, все ссылки, использующиеся для установки свойства в Threaded-объекте отделены от ссылок внутри Threaded-объекте. Чтение тех же данных можно производить напрямую из любого контекста по ссылке на Threaded-объекте.

Статические свойства: Когда создается новый контекст (Thread или Worker), они просто копируются, но ресурсы и объекты обнуляются (из соображения безопасности). Это позволяет использоваь их как локальные для потока хранилища. К примеру, во время создания контекста, для класса, статические свойства которого хранят информацию о соединении к БД и само соединение, будет скопирована только информация необходимая для соединения, но не само соединение. Это позволит создать новое соединение в новом контексте и сохранить его в том же месте никак не затрагивая оригинальный контекст.

Предостережение

Когда запускаются print_r, var_dump или другие отладочные функции, они не включают защиту от рекурсии.

Замечание:

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

Предостережение

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