我正在玩 pthreads 3.1.6-dev 和 PHP 7.1。我的目标是创建一个小型网络爬虫。
计划的工作流程是:您将一个 URL 放入池中(可能是主页),然后一个爬虫(扩展 Threaded)从该 URL 中捕获所有链接。经过小过滤后,爬虫应将所有新链接添加到池中(不应将外部链接添加到池中)。或者,爬虫将新网址提供给“其他人”,将其添加到池中。
该过程应继续进行,直到找不到新的 URL。
我的问题是我没有找到可行的解决方案。我当前的绘制如下所示:爬虫提取 url 并将其放入池中。为此,每个 Worker 都有一个对池的引用,以便爬虫可以通过 Worker 访问池对象。
这个解决方案的问题:如果一个“迟到的”线程将一个新的线程添加到池中,这个新任务将不会执行。
一些演示代码:
class WebWorker extends Worker
{
public function __construct(WebPool $pool)
{
$this->pool = $pool;
print_r("Create a new worker\n");
}
public function run()
{
print_r("Worker {$this->getThreadId()}: " . __METHOD__ . "\n");
}
public function getPool()
{
return $this->pool;
}
private $pool;
}
class WebWork extends Threaded
{
public function run()
{
print_r("Webwork from Worker {$this->worker->getThreadId()}\n");
if (rand(0, 10) > 5) {
print_r("Webwork {$this->worker->getThreadId()} add new Webwork\n");
$this->worker->getPool()->submit(new WebWork());
}
}
}
class WebPool extends Pool
{
public function __construct($size, $class)
{
parent::__construct($size, $class, [$this]);
}
}
$pool = new WebPool(2, 'WebWorker');
$pool->submit(new WebWork());
$pool->submit(new WebWork());
$pool->submit(new WebWork());
$pool->submit(new WebWork());
while ($pool->collect(function ($work) {
return $work->isGarbage();
})) continue;
$pool->shutdown();
一个示例结果:
Create a new worker
Worker 139878744053504: WebWorker::run
Webwork from Worker 139878744053504
Create a new worker
Worker 139878731872000: WebWorker::run
Webwork from Worker 139878731872000
Webwork from Worker 139878731872000
Webwork 139878731872000 add new Webwork
Webwork from Worker 139878744053504
Create a new worker
Worker 139878719289088: WebWorker::run
Webwork from Worker 139878719289088
Webwork 139878719289088 add new Webwork
有人可以告诉我这个问题的最佳实践吗?