Programster's Blog

Tutorials focusing on Linux, programming, and open source

Set up Latest Dev PHP with Multithreading on Ubuntu 16.04

PHP can support multithreading for compute intensive workloads. This tutorial will recompile PHP from source 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.

The majority of the content in the answer below came from an answer on Stack Overflow for how to install php7 (zts) + pthreads on Ubuntu 14.04. However I have tweaked it as necessary for Ubuntu 16.04 and without even trying to add FPM support.

This tutorial will set up the latest version of PHP from the source code. This is not a release, and thus should not be used in production. This tutorial will form a foundation on which I will create production suitable versions in future, using releases of PHP.

Related Posts

Requirements

  • 1GiB Ram - lower than this and your compilation step may fail

Video Runthrogh

Recompile PHP

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 

Remove any existing php7 and recreate php7 and other subdirectories

sudo rm -rf /etc/php7
sudo mkdir -p /etc/php7
sudo mkdir -p /etc/php7/cli
sudo mkdir -p /etc/php7/etc

Go to your home directory. And download the PHP source code that we will compile PHP from.

cd $HOME
git clone https://github.com/php/php-src.git --depth=1

Download the pthreads source to the extensions folder.

cd $HOME/php-src/ext
git clone https://github.com/krakjoe/pthreads -b master pthreads
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

Build PHP.

make && sudo make install

Add Pthreads

We are going to manually compile and add pthreads to PHP, so make the phpize and php-config helper programs executable

sudo chmod o+x /etc/php7/bin/phpize
sudo chmod o+x /etc/php7/bin/php-config

Run phpize on pthreads.

cd $HOME/php-src/ext/pthreads*
/etc/php7/bin/phpize

Set configuration options for pthreads. --enable-pthreads=shared is the main aspect of the configuration

./configure \
--prefix='/etc/php7' \
--with-libdir='/lib/x86_64-linux-gnu' \
--enable-pthreads=shared \
--with-php-config='/etc/php7/bin/php-config'

Build and install the extension

make && sudo make install
sudo cp php.ini-production /etc/php7/cli/php-cli.ini

echo "extension=pthreads.so" | sudo tee -a /etc/php7/cli/php-cli.ini
echo "zend_extension=opcache.so" | sudo tee -a /etc/php7/cli/php.ini

Remove any link to PHP if it already exists. If this was a server from scratch and you only ran the steps in this tutorial, this step should do nothing.

sudo rm /usr/bin/php

Link to your newly compiled PHP binary.

sudo ln -s /etc/php7/bin/php /usr/bin/php

Testing

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