PHP(swoole)多进程,让你的CPU火力全开

什么是进程
进程就是正在运行的程序的一个实例。将大任务划分成多个小任务;
php机制本身不提供多线程的操作,ptcl扩展提供了php操作linux多进程的接口。
个人感觉swoole的多进程process方法更加方便一些。


image.png

可移步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;
image.png

扩展一下,对于如何充分利用多核来提高效率的问题,答案就是:多开几个进程(补充:这里特指针对单进程而言;而且并不是进程越多越好,一般而言与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核数一样

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前文再续,就书接上一回,随着与Server、TCP、Protocol的邂逅,Swoole终于迎来了自己的故事,今天...
    蜗牛淋雨阅读 5,721评论 1 14
  • 出处:韩天峰 网址:rango.swoole.com/archives/508 并发IO问题一直是后端编程中的技术...
    meng_philip123阅读 6,957评论 1 38
  • 并发IO问题一直是服务器端编程中的技术难题,从最早的同步阻塞直接Fork进程,到Worker进程池/线程池,到现在...
    零一间阅读 5,659评论 1 34
  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 9,615评论 0 23
  • 小雅,全名爱雅林,同事们玩笑般起的名字,原是某同事从工地上带给我的流浪猫的孩子,如今已有三岁多,生日不详。 刚接手...
    zhaorong阅读 1,521评论 0 1