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.
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
- 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