由于项目需要,需要使用php cli模式,用于处理Redis的Notification通告。考虑到并发的问题,于是就想到了在PHP中使用多线程的形式。若要在PHP中使用多线程,你需要启用pthreads组件。pthread当前是v3版本,仅能够在PHP 7.2+的CLI模式下使用,同时你需要确保PHP的版本是ZTS
(Zend Thread Safe,线程安全版)。
编译环境
- 操作系统:Ubuntu 20.04 LTS
- PHP源代码版本:7.2.34 ( php/php-src at PHP-7.2.34 (github.com) )
- pthreads: krakjoe/pthreads: Threading for PHP – Share Nothing, Do Everything :) (github.com)
- 本文出自@悠然品鉴,转载请务必注明出处
安装依赖库
由于编译过程需要用到一些库,你需要sudo apt install
如下的一些工具集
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 libtidy-dev
如果你在编译的过程中出现找不到某些库的问题,请自行Google/Baidu解决,我在编译的时候只安装了上面的这些库就完成了。
开始执行编译(务必在同一个终端中)
1、设置一些基础的环境变量
#我们以在家目录进行编译为例
cd ~
#所使用的PHP版本
VERSION=7.2.34
#PHP的安装目录
PHP_INSTALL_DIR=/etc/phpz
#PHP配置文件所在的目录,也就是这个目录下的php.ini文件
PHP_CONFIG_FILE_PATH=${PHP_INSTALL_DIR}/cli
#你可能安装了其NTS版本的PHP,为了避免命名冲突,这里起了个别名
PHP_BIN_ALIAS=phpz
2、创建PHP安装目录以及配置目录
#创建对应的文件夹
sudo mkdir -p ${PHP_INSTALL_DIR}
sudo mkdir -p ${PHP_CONFIG_FILE_PATH}
3、下载源码并解压到当前文件夹
wget -O- https://www.php.net/distributions/php-${VERSION}.tar.gz | tar -xz
4、进入到ext目录中并下载pthreads
#进入到 ext目录
cd php-${VERSION}/ext
#git下载pthreads到ext目录
git clone --recursive https://github.com/krakjoe/pthreads.git
5、配置编译选项
#返回到我们的源代码目录
cd ..
#编译配置,--force清除掉之前的配置
./buildconf --force
#这是编译配置的参数,with-config-file-path指定php.ini的位置,with-config-file-scan-dir指定额外配置文件所在的目录
CONFIGURE_STRING="--prefix=${PHP_INSTALL_DIR} \
--with-config-file-path=${PHP_CONFIG_FILE_PATH} \
--with-config-file-scan-dir=${PHP_INSTALL_DIR}/conf.d \
--disable-cgi \
--with-bz2 \
--with-zlib \
--enable-soap \
--enable-intl \
--with-openssl \
--with-curl \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--enable-pcntl \
--enable-exif \
--with-xsl \
--enable-bcmath \
--enable-mbstring \
--enable-calendar \
--with-tidy \
--enable-maintainer-zts \
--enable-pthreads=shared"
#configure,指定参数是我们上面的那个环境变量
./configure ${CONFIGURE_STRING}
其实我只需要CURL、PDO、PTHREADS、MBSTRING、OPENSSL模块,不过这里直接复制了别人的配置,也没啥问题。如果./configure没有问题的话,将会显示类似于如下的内容:
6、编译并安装
#make , nproc是获取当前CPU核心数
make -j$(nproc)
#生成的pthreads.so 在./modules目录下
sudo make install
make的过程根据你的机器性能,可能会比较漫长。等待完成之后在执行make install完成安装。不出意外,此时你的PHP安装目录已经有了对应的文件了。
7、拷贝配置文件并创建软链接
#拷贝一份production 的配置到我们的php配置文件目录中,并命名为php.ini文件
sudo cp php.ini-production ${PHP_CONFIG_FILE_PATH}/php.ini
#向配置文件中写入extension扩展信息
echo "extension=pthreads.so" | sudo tee -a ${PHP_CONFIG_FILE_PATH}/php.ini
echo "zend_extension=opcache.so" | sudo tee -a ${PHP_CONFIG_FILE_PATH}/php.ini
#创建一个软链接,将我们的PHP可执行文件链接到/usr/bin目录下,名称为我们所设置的别名
sudo ln -s ${PHP_INSTALL_DIR}/bin/php /usr/bin/${PHP_BIN_ALIAS}
8、测试一下
在终端中输入 phpz -r "var_dump( class_exists('Thread') );"
(这里的phpz是我为编译的PHP所起的别名),如果执行结果输出 bool(true) ,那么恭喜你,此时带有pthreads库的PHP ZTS版本已经创建完成了,接下来你就可以在代码中使用Thread了。
其他
本文中,我选择的是PHP 7.2.34版本。我测试过PHP 7.4的版本,但是没有成功。对于其他的版本,请自行测试。
PHP是世界上最好的语言 !