多线程和单线程在Python中提供了相同的性能

2024-09-29 23:16:10 发布

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

在下面的代码中,如果我注释“第6行”并取消注释“第3,4,5行”。代码在主线程中运行,耗时17秒

现在,如果我取消注释“第6行”并注释“第3、4、5行”。取消注释“第1行”和注释“第2行”,然后代码在多线程中运行(创建了3个线程),所用时间再次为17秒。所以多线程和单线程占用的时间是相同的

现在,如果我取消注释“第6行”并注释“第3、4、5行”。注释“第1行”和取消注释“第2行”,然后代码在多进程中运行(创建了3个进程),所用时间为9秒。与单踏板和多踏板相比,多处理工作速度更快

请让我们知道为什么多线程性能与单线程相同

import threading
import time
import multiprocessing
import multiprocessing.pool

class xyz:
    def __init__(self):
        self.data = []
        pass
    def loopData(self):
        item = range(0, 100000000)
        for i in item:
            self.data.append(i)

    def loopDatamulti(self):
        num_of_thread = 3
        thread_list = []
        while True:
            t = threading.Thread(target=self.loopData, args=()) #line 1
            #t = multiprocessing.Process(target=self.loopData,args=()) #line 2
            thread_list.append(t)
            
            num_of_thread_created = len(thread_list)
            if num_of_thread_created == num_of_thread:
                break

        for t in thread_list:
            t.start()

        for t in thread_list:
            t.join()

def main():
    print("Start")
    start_time = time.time()

    xa = xyz()
    #xa.loopData() #line 3
    #xa.loopData() #line 4
    #xa.loopData() #line 5
    xa.loopDatamulti() #line 6
    end_time = time.time()
    strLog = "total time {}".format(end_time - start_time)
    print(strLog)

if __name__ == "__main__":
    main()

Tags: of代码importselffortimedefline
2条回答

多线程不太适合执行纯CPU密集型的函数。如果这样的函数永远不会产生CPU(例如,对于某种类型的I/O),它们只会“锁定”单个CPU,而您将不会获得任何好处。这就是多处理发挥作用的地方。即使这样,您也需要小心,因为如果您的函数是短期的,那么创建单独进程的开销可能会超过您可能期望的优势。下面是一个多处理的示例。使用变量iter和PROCS来查看行为是如何变化的,你就会明白这一点。函数(myFunc)只是执行任意伪随机计算并构建一个要返回的列表

from datetime import datetime
from multiprocessing import Pool
import math
import random

ITERS = 100_000
PROCS = 100


def myFunc(r):
    return [(math.sqrt(random.randint(1, 2000))**2)**(1 / 3) for _ in range(r)]


if __name__ == '__main__':
    _start = datetime.now()

    with Pool() as pool:
        for p in [pool.apply_async(func=myFunc, args=(ITERS,))
                  for _ in range(PROCS)]:
            p.wait()

    _end = datetime.now()

    print(f'Multi-processing duration={_end-_start}')

    _start = datetime.now()

    for I in range(PROCS):
        myFunc(ITERS)

    _end = datetime.now()

    print(f'Single-threaded duration={_end-_start}')

在我的机器上,ITERS和PROCS的值如代码所示,输出如下:-

多处理持续时间=0:00:01.526478
单线程持续时间=0:00:09.776963

在python中有一种称为全局解释器锁的东西,它确保在同一时间只运行代码的一部分(例如,一个函数锁定解释器,另一个代码必须等待它)。其原因与python如何释放未使用的变量有关(通过计算每个变量的引用数)

你可以在这里读到:https://realpython.com/python-gil/

多处理通过创建操作系统级别的进程来解决这个问题,以便实际并行化代码。通过这样做,您可以得到多个进程,每个进程都有自己的python解释器,因此也有自己的全局解释器锁

相关问题 更多 >

    热门问题