什么是进程
进程就是正在运行的程序的一个实例。将大任务划分成多个小任务;
php机制本身不提供多线程的操作,ptcl扩展提供了php操作linux多进程的接口。
个人感觉swoole的多进程process方法更加方便一些。
可移步swoole官网查看详细文档 https://wiki.swoole.com/wiki/page/p-process.html;
swoole_process 是swoole提供的进程管理模块,用来替代PHP的pcntl扩展。
swoole提供的多进程扩展基本功能和pcntl提供的一样,但swoole更易简单上手,并且提供了:
默认基于unixsock的进程间通信;
支持消息队列作为进程间通信;
基于signalfd和eventloop处理信号,几乎没有任何额外消耗;
高精度微秒定时器;
配合swoole_event模块,创建的PHP子进程可以异步的事件驱动模式.
swoole_process 模块提供的方法(Method)主要分为四部分:
1.基础方法
swoole_process::__construct
swoole_process->start
swoole_process->name
swoole_process->exec
swoole_process->close
swoole_process->exit
swoole_process::kill
swoole_process::wait
swoole_process::daemon
swoole_process::setAffinity
2.管道通信
swoole_process->write
swoole_process->read
swoole_process->setTimeout
swoole_process->setBlocking
3.消息队列通信
swoole_process->useQueue
swoole_process->statQueue
swoole_process->freeQueue
swoole_process->push
swoole_process->pop
4.信号与定时器
swoole_process::signal
swoole_process::alarm
实例-引起兴趣
大任务划分成多个小任务
将循环执行的任务,划分为多个进程执行,提高工作效率
假设我们现在有一个通过curl抓取网页内容的需求,需要抓取10个网页,url地址通过数组读取,每个curl耗时2s。如果我们通过for循环来抓取这10个网页,需要耗时20s,使用多进程我们可以将任务划分成5份,分别由5个进程执行,每个进程抓取2个url,并发执行,共耗时4s,效率提高5倍。
$star = time();
$workers = [];
$urls = [
'http://baidu.com/1','http://baidu.com'/2,'http://baidu.com/3',
'http://baidu.com/4','http://baidu.com'/5,'http://baidu.com/6',
'http://baidu.com/7','http://baidu.com'/8,'http://baidu.com/9',
'http://baidu.com/10'
];
for($i = 0; $i < 6; $i++) {
// 子进程
$process = new swoole_process(function(swoole_process $worker) use($i, $urls) {
// curl
$content1 = curlData($urls[$i*2]);
$content2 = curlData($urls[($i*2)+1]);
//echo $content.PHP_EOL;
$worker->write($content1.'--'.$content2.PHP_EOL);
}, true);
$pid = $process->start();
$workers[$pid] = $process;
}
foreach($workers as $process) {
echo $process->read();
}
/**
* 模拟请求URL的内容 1s
* @param $url
* @return string
*/
function curlData($url) {
// curl file_get_contents
sleep(2);
return $url . "success".PHP_EOL;
}
$end = time();
$end = $end - $star;
echo 'time:'.$end;
扩展一下,对于如何充分利用多核来提高效率的问题,答案就是:多开几个进程(补充:这里特指针对单进程而言;而且并不是进程越多越好,一般而言与CPU线程数相当为佳)。
进程数设置需要考虑以下条件
1、cpu核数
2、内存大小
3、业务偏向IO密集还是CPU密集型
进程数设置原则
1、每个进程占用内存之和需要小于总内存(一般来说每个业务进程占用内存大概40M左右)
2、如果是IO密集型,也就是业务中涉及到一些阻塞式IO,比如一般的访问Mysql、Redis等存储都是阻塞式访问的,进程数可以开大一些,如配置成CPU核数的3倍。如果业务中涉及的阻塞等待很多,可以再适当加大进程数,例如CPU核数的5倍甚至更高。注意非阻塞式IO属于 CPU密集型,而不属于IO密集型。
3、如果是CPU密集型,也就是业务中没有阻塞式IO开销,例如使用异步IO读取网络资源,进程不会被业务代码阻塞的情况下,可以把进程数设置成和CPU核数一样