使用ThreadPoolExecu时,多线程没有好处

2024-05-13 21:31:02 发布

您现在位置:Python中文网/ 问答频道 /正文

为了得到一些统计数据,我试图模拟一些过程。我决定使用多个线程编写模拟程序,因为每个测试运行都是独立的。你知道吗

这意味着如果我需要执行1000次测试运行,那么应该可以有4个线程(每个线程执行250次测试运行)。你知道吗

在执行此操作时,我发现添加多个线程并不会减少模拟时间。你知道吗

我有4个物理内核的Windows10笔记本电脑。你知道吗

我写了一个简单的程序来展示我所说的行为。你知道吗

from concurrent.futures import ThreadPoolExecutor
import time
import psutil
import random


def runScenario():
    d = dict()
    for i in range(0, 10000):
        rval = random.random()
        if rval in d:
            d[rval] += 1
        else:
            d[rval] = 1
    return len(d)    

def runScenarioMultipleTimesSingleThread(taskId, numOfCycles):
    print('starting thread {}, numOfCycles is {}'.format(taskId, numOfCycles))

    sum = 0
    for i in range(numOfCycles):
        sum += runScenario()

    print('thread {} finished'.format(taskId))

    return sum

def modelAvg(numOfCycles, numThreads):

    pool = ThreadPoolExecutor(max_workers=numThreads)

    cyclesPerThread = int(numOfCycles / numThreads)
    numOfCycles = cyclesPerThread * numThreads

    futures = list()
    for i in range(numThreads):
        future = pool.submit(runScenarioMultipleTimesSingleThread, i, cyclesPerThread)
        futures.append(future)

    sum = 0
    for future in futures:
        sum += future.result()

    return sum / numOfCycles


def main():
    p = psutil.Process()
    print('cpus:{}, affinity{}'.format(psutil.cpu_count(), p.cpu_affinity() ))

    start = time.time()
    modelAvg( numOfCycles = 10000, numThreads = 4)
    end = time.time()

    print('simulation took {}'.format(end - start))

if __name__ == '__main__':
    main()

结果如下:

一个线程:

cpus:8, affinity[0, 1, 2, 3, 4, 5, 6, 7]
starting thread 0, numOfCycles is 10000
thread 0 finished
simulation took 23.542529582977295

四个线程:

cpus:8, affinity[0, 1, 2, 3, 4, 5, 6, 7]
starting thread 0, numOfCycles is 2500
starting thread 1, numOfCycles is 2500
starting thread 2, numOfCycles is 2500
starting thread 3, numOfCycles is 2500
thread 1 finished
thread 2 finished
thread 0 finished
thread 3 finished
simulation took 23.508538484573364

我期望当使用4个线程时,模拟时间应该理想地小4倍,当然它不应该是相同的。你知道吗


Tags: inimportfortimeisdef线程thread
1条回答
网友
1楼 · 发布于 2024-05-13 21:31:02

当您使用cPython时,通过在线程之间分配计算负载,您不会得到显著的加速。这是因为cPython中的内存访问是使用Python GIL mechanism(全局解释器锁)序列化的。例如,我在处理文本时遇到过这种情况。你知道吗

在这种情况下,如果您监视您的CPU,您可能会看到您的进程没有充分利用其中的4个,每个只有25%。你知道吗

您可以使用MultiProcessing将负载真正分布在cpu上。你知道吗

在Python中,当线程是IO绑定的(比如oposed到CPU绑定的)时,线程仍然可以提供性能改进。你知道吗

相关问题 更多 >