1

Python を使用して Web サイトのスパイダーを作成するのに問題があります。基本的な考え方は次のとおりです。

キューがあり、各スレッドはキューから URL を取得し、関数getAllLinksを呼び出してその URL からリンクを取得します。疑似コードは次のとおりです。

class Spider(Threading.Thread):
    def __init__(self):
        self.queue = Queue.Queue

    def run(self):
        while True:
            url = self.queue.get()
            getAllLinks(url)  
            time.sleep(0.1)   #I try to release the GIL

しかし問題は、getAllLinks を呼び出した後に手動でスレッドを切り替えても、プログラムはシングルスレッドのものほど高速ではないということです。より良い方法はありますか?

複数のスレッドを使用してスパイダーの処理速度を上げたいのですがtime.sleep()、スレッドに強制的に GIL を解放させるため、遅いと思います。

これは次のようなものだと思います: for url in urlList: spider(url). の後にのみスレッドを切り替えるのではなくgetAllLinks()、基本的に 1 つのスレッドを使用するのと同じですか?

4

1 に答える 1

0

したがって、マルチスレッド プログラムは、シングルスレッド バージョンよりも大幅に高速ではありません。

CPython インタープリターが100 バイト コードごとにグローバル インタープリター ロック (GIL) を解放するという点で、あなたは正しいです。残念ながら、GIL は、I/O をあまり使用しないマルチスレッド プログラムを役に立たなくします。

GIL は、純粋な Python で作業している人々が複数のコアを真に活用することを妨げますか? 簡単に言えば:はい、そうです。スレッド自体は言語構造ですが、インタープリターはスレッドと OS 間のマッピングのゲートキーパーです。(ソース)。

しかし、あなたは I/O を広範囲に使用していると言います。I/O が完了すると GIL が解放されます。つまり、プログラムはマルチスレッドを使用して速度の結果を確認できます。

したがって、コードをgetAllLinks関数に投稿してください。そうすることで、機能しているものと機能していないものをベンチマークできます。また、 を使用time.sleep(.0001)して GIL をだまして解放させることもできますが (よりも小さい数値0.1を使用します)、多くの I/O を使用しているため、このハックは必要ありません。その行を削除します。

于 2012-07-18T17:15:49.747 に答える