Install PHP 7.0 With Pthreads on Ubuntu 16.04
Update - 30th Jan 2018
Please no longer use this tutorial. Instead use pthreads with PHP 7.2.
I spent ages trying to debug odd results in my code until I discovered on the pthreads github page that:
...only PHP 7.2+ is now supported (requiring the current master branch of pthreads). This is due to safety issues with ZTS mode on PHP 7.0 and 7.1.
Outdated Info
PHP can support multithreading for compute intensive workloads. The tutorial below is divided into two parts. The first part will recompile PHP with ZTS enabled in order to allow us to then add the pthreads extension for the PHP CLI (not for Apache or FPM). I will not dive into when not to use multithreading in PHP, but its fair to say that there are good reasons why it supported for the webserver, and hence the pre-built package that you install from the Ubuntu repositories.
Requirements
- 1GiB Ram - lower than this and your compilation step may fail
Video Walkthrough
Compile PHP
The first thing we need to do is compile our own version of PHP that will be able to support the installation of the pthreads extension.
Download the necessary packages for compilation.
sudo apt update && \
sudo apt install -y libzip-dev bison autoconf build-essential pkg-config git-core \
libltdl-dev libbz2-dev libxml2-dev libxslt1-dev libssl-dev libicu-dev \
libpspell-dev libenchant-dev libmcrypt-dev libpng-dev libjpeg8-dev \
libfreetype6-dev libmysqlclient-dev libreadline-dev libcurl4-openssl-dev
Install pear for installing pthreads later.
sudo apt-get install php7.0-dev php-pear -y
The previous command will have installed PHP, so remove it
sudo apt-get remove php-cli -y
Go to your home directory. We will perform all of our work in here.
cd $HOME
Go to the releases page and grab the .tar.gz link for the latest release for the version of PHP you want. By the time you read this tutorial, these versions are likely to be out of date but serve as a working example.
wget https://github.com/php/php-src/archive/php-7.0.27.tar.gz
Extract the source code and rename it to php-src so the rest of the steps in this tutorial work no matter what version you are running.
tar --extract --gzip --file php-*
rm php-*.tar.gz
mv php-src-* php-src
cd $HOME/php-src
./buildconf --force
CONFIGURE_STRING="--prefix=/etc/php7 \
--with-bz2 \
--with-zlib \
--enable-zip \
--disable-cgi \
--enable-soap \
--enable-intl \
--with-openssl \
--with-readline \
--with-curl \
--enable-ftp \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--enable-sockets \
--enable-pcntl \
--with-pspell \
--with-enchant \
--with-gettext \
--with-gd \
--enable-exif \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-xsl \
--enable-bcmath \
--enable-mbstring \
--enable-calendar \
--enable-simplexml \
--enable-json \
--enable-hash \
--enable-session \
--enable-xml \
--enable-wddx \
--enable-opcache \
--with-pcre-regex \
--with-config-file-path=/etc/php7/cli \
--with-config-file-scan-dir=/etc/php7/etc \
--enable-cli \
--enable-maintainer-zts \
--with-tsrm-pthreads \
--enable-debug \
--enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data"
./configure $CONFIGURE_STRING
--enable-maintainer-zts
and --enable-debug
.
Build PHP.
make && sudo make install
Update the symlink for php to point to our custom build.
sudo rm /usr/bin/php
sudo ln -s /etc/php7/bin/php /usr/bin/php
Testing PHP Installation
You have now compiled PHP 7.0 from source with the necessary configuration necessary for installing pthreads later.
You can check your version by running:
php -v
You can also check that you have ZTS support which is required for pthreads:
php -a
echo PHP_ZTS; // this should output a 1 and not a 0
Install Pthreads
You have completed the first step of the tutorial which is to build your own version of PHP that will support installing pthreads. Now it is time to actually add the extension.
Use PECL to install the pthreads extesion
sudo pecl install pthreads
PHP.INI
At the end of the previous step, the console will have told you that you need to add extension=pthreads.so
to your php.ini
file.
However, we don't have one yet for our custom built PHP so lets create it.
sudo mkdir -p /etc/php7/cli/
sudo cp /usr/lib/php/7.0/php.ini-production.cli /etc/php7/cli/php.ini
Now add the pthreads extension to the php ini file ( and opcache whilst we're in there).
echo "extension=pthreads.so" | sudo tee -a /etc/php7/cli/php.ini
echo "zend_extension=opcache.so" | sudo tee -a /etc/php7/cli/php.ini
Testing Threading Support
You can check which version of PHP you have installed by running:
php --version
Multithreading Test
In order to test that multithreading was now available in the PHP CLI, I tweaked a script from a tutorial on Sitepoint and put it below
<?php
class Task extends Threaded
{
private $value;
public function __construct(int $i)
{
$this->value = $i;
}
public function run()
{
$s=0;
for ($i=0; $i<10000; $i++)
{
$s++;
}
echo "Task: {$this->value}\n";
}
}
# Create a pool of 4 threads
$pool = new Pool(4);
for ($i = 0; $i < 15000; ++$i)
{
$pool->submit(new Task($i));
}
while ($pool->collect());
$pool->shutdown();
As you can see below, when I run the script, I have 5 PHP threads, one from the main thread, and then the 4 workers in the pool that I created.
Conclusion
We now have support for multithreading in PHP on Ubuntu 16.04. If you wish to learn more about how to make use of pthreads, I recommend reading "Parallel Programming with Pthreads in PHP – the Fundamentals" and the man pages of course.
References
- Stack Overflow - how to install php7 (zts) + pthreads on Ubuntu 14.04
- Stack Overflow - How can one use multi threading in PHP applications
- Tutorial: Multi-Threading in PHP7 w/ pThreads
- FLOWL - Compile PHP 5.6 with pthreads and ZTS Ubuntu/Debian
- Stack Overflow - Recompile PHP with ZTS enabled on Ubuntu
First published: 16th August 2018