2

私は最初にこの問題を製品コードで確認し、次にプロトタイプを作成しました。

import threading, Queue, time, sys

def heavyfunc():
    ''' The idea is just to load CPU '''
    sm = 0
    for i in range(5000):
        for j in range(5000):
            if i + j % 2 == 0:
                sm += i - j
    print "sm = %d" % sm

def worker(queue):
    ''' worker thread '''
    while True:
        elem = queue.get()
        if elem == None: break
        heavyfunc()           # whatever the elem is


starttime = time.time()  

q = Queue.Queue()             # queue with tasks

number_of_threads = 1
# create & start number_of_threads working threads
threads = [threading.Thread(target=worker, args=[q]) for thread_idx in range(number_of_threads)]
for t in threads: t.start()

# add 2 working items: they are estimated to be computed in parallel
for x in range(2):
    q.put(1)

for t in threads: q.put(None) # Add 2 'None' => each worker will exit when gets them
for t in threads: t.join()    # Wait for every worker

#heavyfunc()

elapsed = time.time() - starttime

print >> sys.stderr, elapsed

Heavyfunc() の考え方は、同期や依存関係なしで、CPU をロードすることだけです。

1 つのスレッドを使用する場合、平均で 4.14 秒かかります 2 つのスレッドを使用する場合、平均で 6.40 秒かかります スレッドを使用しない場合、heavyfunc() を計算するには、平均で 2.07 秒かかります (何度も測定すると、正確に 4.14 / 2 になります。 1 つのスレッドと 2 つのタスクの場合)。

2 つのスレッドがある場合、heavyfunc() を使用した 2 つのジョブに 2.07 秒かかると予想しています。(私のCPUはi7です=>十分なコアがあります)。

これは、真のマルチスレッドが存在しなかったという考えを与える CPU モニターのスクリーンショットです。

CPU負荷グラフ

私の考えのどこが間違っているのでしょうか?干渉しない n 個のスレッドを作成するにはどうすればよいですか?

4

1 に答える 1

5

CPython は一度に複数のコアでバイトコードを実行しません。マルチスレッドの CPU バウンド コードは無意味です。Global Interpreter Lock (GIL) は、プロセス内のすべての参照カウントを保護するために存在するため、一度に 1 つのスレッドのみが Python オブジェクトを使用できます。

一度に 1 つのスレッドしか動作していないため、パフォーマンスが低下していますが、スレッド コンテキストも変更しています。

于 2012-06-28T15:56:10.637 に答える