思路:利用pcntl生成一个子进程处理异步任务,处理完后杀掉子进程。
依赖:该功能依赖于php pcntl扩展,使用前需先安装该扩展
查看是否已经安装pcntl扩展
$ php -m |grep pcntl
pcntl
安装pcntl扩展(已经安装则忽略该步骤)
//根据自己的php版本下载源码包并解压
$ tar xvf php-7.1.27.tar.gz
$ cd php-7.1.27/ext/pcntl/
//源码编译扩展
$ phpize
$ ./configure --with-php-config=/usr/bin/php-config
$ make
$ make install
//在php.ini文件添加以下行
extension=pcntl.so
基于pcntl的异步工具类Async.php
class Async
{
/**
* 异步任务
* @params $func 要异步执行的函数
* @params $params 要传递给$func的参数
*/
public static function asyncTask(callable $func, ...$params)
{
pcntl_signal(SIGCHLD, SIG_IGN); //安装监听信号
$pid = pcntl_fork(); //生成一个线程
if ($pid == -1) {
exit('could not fork for client');
}
//父进程(pid大于0为父进程,pid为子进程的id)
else if ($pid) {
return $pid;
}
//子进程(pid为0则为子进程)
else {
try {
//执行用户函数
call_user_func_array($func, $params);
} finally {
//执行完后杀死进程
posix_kill(posix_getpid(), SIGKILL);
exit(0);
}
}
}
}
main.php调用异步函数
<?php
require 'Async.php';
//需要异步执行的函数
$func = function($p1){
//休眠1秒
sleep(1);
//打印参数
echo $p1;
};
//异步执行函数
Async::asyncTask($func, "world\n");
//同步执行的操作,先于Async::asyncTask执行
echo "hello ";
sleep(1);
由于异步线程只能输出到控制台,示例采用控制台执行main.php文件:
$ php main.php
#输出结果
hello world