ホームページ  >  記事  >  バックエンド開発  >  PHP を使用して非同期マルチスレッド クローラーを実装する方法

PHP を使用して非同期マルチスレッド クローラーを実装する方法

PHPz
PHPzオリジナル
2023-06-13 13:31:411290ブラウズ

Web クローラーの実装では、非同期マルチスレッドによってクロールの効率が大幅に向上します。主流のプログラミング言語である PHP では、並行プログラミングにより非同期マルチスレッド クローラーを実装することもできますので、この記事ではその具体的な実装方法を紹介します。

1. 非同期マルチスレッド クローラーの概要

非同期マルチスレッド クローラーは主に、非同期 IO とマルチスレッド処理という 2 つのテクノロジーに依存しています。従来の同期 IO では、スレッドは IO 操作が完了するのを待ってから次のステップに進みます。非同期 IO では、スレッドは IO 操作を待機している間に他の操作を実行できるため、プログラムの実行効率が向上します。マルチスレッドでは複数のタスクを同時に実行できるため、タスクの処理が高速化されます。

2. 非同期マルチスレッドの実装原理

PHP での非同期マルチスレッドの実装は、主に pthread と cURL という 2 つの拡張機能に依存します。 pthread 拡張機能は、POSIX スレッド標準に基づくマルチスレッド拡張機能であり、PHP でマルチスレッド機能を有効にすることができます。 cURL は PHP で使用されるネットワーク ライブラリであり、cURL を介したネットワーク データの送信を実現できます。

非同期マルチスレッド クローラーを実装する主なプロセスは次のとおりです。

  1. メイン スレッドと複数のサブスレッドを作成します。サブスレッドは作成および破棄できます。必要に応じて。
  2. メインスレッドが開始されると、タスクキューから保留中のタスクを取り出し、そのタスクを子スレッドに割り当てて処理します。
  3. 子スレッドが開始されたら、cURL を介してネットワーク リクエストを開始し、必要なデータを取得します。
  4. ネットワーク応答を待機している間、サブスレッドは他のタスクを実行して、クローラの動作効率を向上させることができます。
  5. サブスレッドのリクエストが完了すると、クロールされたデータがメインスレッドに送信され、メインスレッドは指定された保存場所に結果を保存します。
  6. タスク キューに処理すべきタスクがまだある場合は、上記の手順を繰り返します。

3. 実装手順

  1. pthread 拡張機能のインストール

Linux では、次のコマンドを使用して pthread 拡張機能をインストールできます。

sudo pecl install pthreads

Windows では、PHP 公式 Web サイトから pthread 拡張 DLL ファイルを入手してインストールできます。

  1. メイン スレッドとサブスレッドの作成

メイン スレッドとサブスレッドの作成は、PHP の Thread クラスを通じて実行できます。

class SpiderThread extends Thread {

private $url;

public function __construct($url) {
    $this->url = $url;
}

public function run() {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $this->url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = curl_exec($ch);
    curl_close($ch);
    $this->synchronized(function($thread){
        $thread->notify();
    }, $this);
    return $result;
}

}

メイン スレッドは、pthread によって拡張された Mutex クラスを通じて同期できます。

$mutex = new Mutex();
$threads = array();
foreach($urls as $url) {

$mutex->lock();
$threads[] = new SpiderThread($url);
end($threads)->start();
$mutex->unlock();
$mutex->synchronized(function($mutex){
    $mutex->wait();
}, $mutex);

}
foreach($threads as $thread) {

$result = $thread->join();
//处理爬取结果

}

上記のコードでは、$urls はクロールされるリンクを格納する配列です。メインスレッドは子を作成します。スレッドはタスク処理を実行し、子スレッドから返された結果は $result に格納されます。

  1. スレッド プールの実装

プログラムの実行効率を向上させるために、スレッド プール テクノロジを使用して子スレッドの作成と破棄を管理できます。スレッド プールには一定数の子スレッドが維持され、メイン スレッドがスレッド プールにタスクを送信すると、スレッド プールはスレッドのリアルタイム ステータスに基づいて、タスク処理用のアイドル スレッドの 1 つを選択します。

次は、単純なスレッド プールの実装例です:

class ThreadPool {

private $pool;
private $tasks;

public function __construct($size) {
    $this->pool = new SplQueue();
    for($i = 0; $i < $size; $i++) {
        $this->pool->enqueue(new SpiderThread());
    }
    $this->tasks = new SplQueue();
}

public function execute($task) {
    if($this->pool->isEmpty()) {
        $this->tasks->enqueue($task);
    } else {
        $thread = $this->pool->dequeue();
        $thread->execute($task);
    }
}

public function addThread($thread) {
    $this->pool->enqueue($thread);
}

public function addTask($task) {
    $this->tasks->enqueue($task);
    $this->checkTask();
}

public function checkTask() {
    if(!$this->tasks->isEmpty() && !$this->pool->isEmpty()) {
        $thread = $this->pool->dequeue();
        $task = $this->tasks->dequeue();
        $thread->execute($task);
    }
}

}

IV. 概要

この記事では、PHP で非同期マルチスレッド クローラーを実装する基本的な方法を紹介します pthread と cURL を通じてマルチスレッドとネットワーク データ送信を実現し、クローラーの動作効率を大幅に向上させます。実際のアプリケーションでは、スレッド プール テクノロジを使用することでプログラムの実行効率をさらに向上させることができます。

以上がPHP を使用して非同期マルチスレッド クローラーを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。