多进程与多线程Python时间

use*_*619 2 python multiprocessing

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

当我比较输出时,我看到多进程应用程序比多线程模块多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()
Run Code Online (Sandbox Code Playgroud)

多进程模块

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()
Run Code Online (Sandbox Code Playgroud)

air*_*rog 7

如果您的计算机上有两个可用的CPU,则您有两个不需要通信的进程,并且您希望使用它们来使程序更快,您应该使用多处理模块,而不是线程模块.

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

但是,在您给出的示例中,您有一个进程非常快速地完成(在我的机器上不到0.1秒),并且一个进程需要大约18秒才能完成另一个进程.具体数字可能因硬件而异.在这种情况下,几乎所有的工作都在一个进程中进行,所以你真的只使用一个CPU.在这种情况下,产生进程与线程的开销增加可能导致基于进程的版本变慢.

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

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

对于第三个问题,确定从额外进程获得多少效率的最简单方法就是使用time.time()您自己或timeLinux中的实用程序来测量程序的总运行时间(例如time python myprog.py).理想的增速应该等于您正在使用的进程数量,等4个CPU运行应该是一个4个处理程序最多有1个过程4倍比同一程序更快,假设你从额外的过程中获得最大收益.如果其他流程对您没那么大帮助,那么它将不到4倍.