php Swoole多线程爬虫 七

280 阅读1分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

课程背景

  • 我作为一个PHP工程师 虽然这几年PHP没落了
  • 但我还是有责任补充一些PHP方面的高级教程
  • 掘金粑粑开始更文奖励了 不能白白拿人家的奖励
  • 应该发表一些高层次的PHP的技术文章 别让PHP倒了

正文开始

上一章节中我们确定了多线程的开启方法。并要确定工作量以后,分配给不同的线程去做即可。

进程之间数据是无法共享的。如何存储需要生成的数据,如何把任务分配给不同的进程呢?

方法有好多,都是借助了一些中间的媒介,我们这里用的是PHP Spl函数库的内容。

1 spl简介 乍一听好像很熟悉,spl库提供了一些高级的功能,平时是很少接触的。可能我们最熟悉的就是自动加载的方法了,spl_autoload_register 目前主流框架,类的加载都是使用这个方法。

image.png

2 SplQueue class

SplQueue 类通过使用一个双向链表来提供队列的主要功能 我们需要进行的任务就用这个队列存储。然后在每一个进程中处理相应的队列即可。

检查发现之前的代码存在问题,splQueue也无法显现所有内存共享数据。所以我们使用 swoole中的数据类型 chan来解决我们上面遇到的问题

示例代码

<?php
$worker_num = 20; //线程数
$num = 2822; //总页数
$base_url = "https://toutiao.sanhao.com/news-list.php?u=p%s";

$queue = new SplQueue();
for ($i=1; $i <= $num; $i++) { 
    $queue->enqueue(sprintf($base_url,$i));
}

for ($i=0; $i < 10; $i++) { 
    $process = new swoole_process(function($pro) use ($queue){
        $url = $queue->dequeue();
        echo $url . PHP_EOL;
    },false);
    $process->start();
}

for ($i=0; $i < 10; $i++) { 
    swoole_process::wait();
}

image.png 可以发现,并没有实现数据在内存中的共享。

下一章节我尝试用别的方法,替代之前代码中的问题。