1

Pythonで2つの長時間実行操作を同時に実行しようとしています。どちらも同じデータセットで動作しますが、変更はしません。スレッド化された実装は、単に次々に実行するよりも実行が遅いことがわかりました。

私が経験していることを示すために、簡単な例を作成しました。

このコードを実行し、46行目をコメント化すると(スレッド化された操作を実行するようになります)、私のマシンでの実行時間は約1:01(分:秒)になります。2つのCPUがフル実行時間で約50%で実行されているのがわかります。

行47をコメントアウトすると(順次計算が発生します)、実行時間は約35秒になり、1つのCPUが完全な実行時間で100%に固定されます。
両方の実行により、両方の完全な計算が完了します。

from datetime import datetime
import threading


class num:
    def __init__(self):
        self._num = 0

    def increment(self):
        self._num += 1

    def getValue(self):
        return self._num

class incrementNumber(threading.Thread):
    def __init__(self, number):
        self._number = number
        threading.Thread.__init__(self)

    def run(self):
        self.incrementProcess()

    def incrementProcess(self):
        for i in range(50000000):
            self._number.increment()


def runThreaded(x, y):
    x.start()
    y.start()
    x.join()
    y.join()

def runNonThreaded(x, y):
    x.incrementProcess()
    y.incrementProcess()

def main():
    t = datetime.now()

    x = num()
    y = num()
    incrementX = incrementNumber(x)
    incrementY = incrementNumber(y)

    runThreaded(incrementX, incrementY)
    #runNonThreaded(incrementX, incrementY)


    print x.getValue(), y.getValue()
    print datetime.now() - t


if __name__=="__main__":
    main()
4

1 に答える 1

4

CPython には、いわゆるGlobal Interpreter Lockがあります。これは、マルチスレッドの場合でも、一度に 1 つの Python ステートメントしか実行できないことを意味します。この制約を回避するmultiprocessingを調べることをお勧めします。

GIL は、Python のマルチスレッドが I/O バウンド操作、何かが起こるのを待つその他の操作、または作業中に GIL を解放する C 拡張機能を呼び出す場合にのみ役立つことを意味します。

于 2012-04-17T17:44:13.773 に答える