0

ローカル ファイル システムから約 110000 以上のテキスト ファイルを読み取り、それらを MongoDB にプッシュする Python プログラムを作成しています。これが私のコードスニペットです。

クラス EmailProducer (threading.Thread):

def __init__(self, threadID, queue, path):
    self.threadID = threadID
    self.queue = queue
    self.path = path
    threading.Thread.__init__(self)

def run(self):
    if (queue.empty()):
        files = os.listdir(self.path)
        print(len(files))
        for file in files:
            queue.put(file)

クラス EmailConsumer (threading.Thread):

def __init__(self, threadID, queue, path, mongoConn):
    self.threadID = threadID
    self.queue = queue
    self.mongoConn = mongoConn
    self.path = path
    threading.Thread.__init__(self)
def run(self):
    while (True):
        if (queue.empty()):
            mongoConn.close()
            break
        file = queue.get()
        self.mongoConn.persist(self.path, file)

EmailProducer インスタンスはローカル ファイル システムからファイルを読み取り、キューが空の場合はキューに格納します。EmailConsumer インスタンスはキューからファイルをフェッチし、それらを Mongo にプッシュします。同じ機能の順次バージョンも作成しました。i-5クアッドコアプロセッサを搭載したubuntu 12.04 32ビットデスクトップで両方を実行し、両方の時間を測定しました。マルチスレッド バージョンは、1 つのプロデューサーと 7 つのコンシューマーから始まりました。ただし、どちらもリアルタイムで約 23.7 秒、ユーザー時間で約 21.7 秒かかります。ここではスレッド化が役立つと思いましたが、数字はそれが役に立たないことを教えてくれました。

その理由について洞察に満ちた考えを持っている人はいますか?

4

2 に答える 2

3

スレッド化は、IO バウンド操作にはあまり役に立ちません。特に、グローバル インタープリター ロックの場合はそうではありません。そのため、一度に実行されるスレッドは 1 つだけでした。スレッドなしでは速くなかったことに驚いています。selectモジュールまたはサードパーティのライブラリを使用して、ファイルを非同期に読み取ることを検討してください。

于 2012-04-06T01:37:26.190 に答える
0

Python スレッド化は、CPythonのGlobal Interpreter Lockによって多少制限されています。これはパフォーマンスの点でかなり劣っていると考えられており、おそらく結果に貢献しています。

すべての C レベル拡張では、外部リソースでブロックしている間、GIL を保持することによって「スレッドの無効化」を回避するために、特定の GIL サポートも必要です。つまり、たとえば MongoDB と対話するために C レイヤー ライブラリを使用している場合、操作中に他のスレッドがブロックされる可能性があります。(そうなるかどうかはわかりませんが、そうなる可能性があるだけです。)

于 2012-04-06T01:43:03.860 に答える