python - 多进程与多线程 Python 耗时

标签 python multiprocessing

我有 2 个简单的函数(在一个范围内循环)可以单独运行而没有任何依赖性。我正在尝试使用 Python 多处理模块和多线程模块来运行这 2 个函数。

当我比较输出时,我看到多进程应用程序比多线程模块多花费 1 秒。

我读到由于全局解释器锁,多线程效率不高......

基于以上说法-
1. 如果两个进程之间没有依赖关系,最好使用多处理吗?
2. 如何计算我可以在我的机器上运行的进程/线程数以实现最大效率..
3.还有,有没有办法通过使用多线程来计算程序的效率...

多线程模块...

from multiprocessing import Process

import thread
import platform

import os
import time
import threading
class Thread1(threading.Thread):
    def __init__(self,threadindicator):
        threading.Thread.__init__(self)
        self.threadind = threadindicator

    def run(self):
        starttime = time.time() 
        if self.threadind == 'A':
            process1()
        else:
            process2()
        endtime = time.time()
        print 'Thread 1 complete : Time Taken = ', endtime - starttime

def process1():
    starttime = time.time() 
    for i in range(100000):
        for j in range(10000):
            pass        
    endtime = time.time() 

def process2():
    for i in range(1000):
        for j in range(1000):
            pass

def main():

    print 'Main Thread'
    starttime = time.time()
    thread1 = Thread1('A')
    thread2 = Thread1('B')
    thread1.start()
    thread2.start()
    threads = []
    threads.append(thread1)
    threads.append(thread2)

    for t in threads:
        t.join()
    endtime = time.time()
    print 'Main Thread Complete , Total Time Taken = ', endtime - starttime


if __name__ == '__main__':
    main()

多进程模块

from multiprocessing import Process
import platform

import os
import time

def process1():
#     print 'process_1 processor =',platform.processor()
    starttime = time.time() 
    for i in range(100000):
        for j in range(10000):
            pass
    endtime = time.time()
    print 'Process 1 complete : Time Taken = ', endtime - starttime 


def process2():
#     print 'process_2 processor =',platform.processor()
    starttime = time.time()
    for i in range(1000):
        for j in range(1000):
            pass
    endtime = time.time()
    print 'Process 2 complete : Time Taken = ', endtime - starttime

def main():
    print 'Main Process start'
    starttime = time.time()
    processlist = []

    p1 = Process(target=process1)
    p1.start()
    processlist.append(p1)

    p2 = Process(target = process2)
    p2.start()
    processlist.append(p2)

    for i in processlist:
        i.join()
    endtime = time.time()
    print 'Main Process Complete - Total time taken = ', endtime - starttime

if __name__ == '__main__':
    main()

最佳答案

如果你的机器上有两个可用的 CPU,你有两个不需要通信的进程,你想同时使用它们来使你的程序更快,你应该使用多处理模块,而不是线程模块。

全局解释器锁 (GIL) 阻止 Python 解释器通过使用多个线程来有效地使用多个 CPU,因为一次只有一个线程可以执行 Python 字节码。因此,多线程不会改善应用程序的整体运行时间,除非您有阻塞调用(例如等待 IO)或释放 GIL(例如 numpy 会为一些昂贵的调用执行此操作)延长的时间。然而,多处理库创建了单独的子进程,因此解释器的多个副本,因此它可以有效地利用多个 CPU。

但是,在您提供的示例中,您有一个进程完成得非常快(在我的机器上不到 0.1 秒),而一个进程在另一个进程上大约需要 18 秒才能完成。确切的数字可能因您的硬件而异。在那种情况下,几乎所有的工作都发生在一个进程中,所以无论如何你实际上只使用了一个 CPU。在这种情况下,生成进程与线程的开销增加可能导致基于进程的版本变慢。

如果您让两个进程都执行 18 秒的嵌套循环,您应该会看到多处理代码运行得更快(假设您的机器实际上有多个 CPU)。在我的机器上,我看到多处理代码在大约 18.5 秒内完成,多线程代码在 71.5 秒内完成。我不确定为什么多线程花费的时间超过 36 秒,但我的猜测是 GIL 导致了某种线程争用问题,这会减慢两个线程的执行速度。

关于您的第二个问题,假设系统上没有其他负载,您应该使用与系统上的 CPU 数量相等的进程数。您可以通过在 Linux 系统上执行 lscpu、在 Mac 系统上执行 sysctl hw.ncpu 或从运行对话框中运行 dxdiag 来发现这一点Windows(可能还有其他方法,但我总是这样做)。

对于第三个问题,计算额外进程的效率的最简单方法就是测量程序的总运行时间,使用 time.time() 作为你是,或者 Linux 中的 time 实用程序(例如 time python myprog.py)。理想的加速应该等于您使用的进程数,因此在 4 个 CPU 上运行的 4 进程程序应该至多比具有 1 个进程的相同程序快 4 倍,假设您获得最大从额外的过程中受益。如果其他流程对您的帮助不大,那么它会不到 4 倍。

关于python - 多进程与多线程 Python 耗时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19326582/

相关文章:

python - 适用于DataFrame操作/功能的Python多重处理

python - 守护进程不允许有 child

python - 如何从 Pandas Dataframe 中提取多个数字

python - 在 Matplotlib 3D 散点图中显示线的长度

python - 将 django 过滤器编译成变量并在运行时执行?

Python多处理队列内存管理

python - 如何使用 joblib 并行化缓存函数

python - 如何在 Python 中优化多处理

python - 如何使用Python打印偶数列表

python - 通过 Selenium 单击链接