1

我发现线程模块比同一个任务需要更多的时间。试用线程和多处理模块,python

import time 
import threading 
import multiprocessing 

def func(): 
    result = 0 
    for i in xrange(10**8): 
     result += i 

num_jobs = 10 


# 1. measure, how long it takes 10 consistent func() executions 
t = time.time() 
for _ in xrange(num_jobs): 
    func() 
print ("10 consistent func executions takes:\n{:.2f} seconds\n".format(time.time() - t))   

# 2. threading module, 10 jobs 
jobs = [] 
for _ in xrange(num_jobs): 
    jobs.append(threading.Thread(target = func, args=())) 
t = time.time() 
for job in jobs: 
    job.start() 
for job in jobs: 
    job.join()  
print ("10 func executions in parallel (threading module) takes:\n{:.2f} seconds\n".format(time.time() - t))   

# 3. multiprocessing module, 10 jobs 
jobs = [] 
for _ in xrange(num_jobs): 
    jobs.append(multiprocessing.Process(target = func, args=())) 
t = time.time() 
for job in jobs: 
    job.start() 
for job in jobs: 
    job.join() 
print ("10 func executions in parallel (multiprocessing module) takes:\n{:.2f} seconds\n".format(time.time() - t)) 

结果:

10个一致FUNC处决需要:在平行 25.66 seconds

10 FUNC处决(穿线模块)需要: 46.00 seconds

10 FUNC执行并行(多处理模块)需要: 7.92 seconds

1)为什么用多处理模块的实施工作比线程模块更好?

2)为什么一致 FUNC处决花费较少的时间,然后使用线程模块?

+0

@AnthonySottile,谢谢,但我的问题是更广泛的你的链接的问题 –

+2

这真的不是 - 这个问题(和几个答案)详细说明,线程是(通常)会变得更慢(对于CPU绑定操作),因为全局解释器锁定,并且多处理和线程都将有一些启动成本。在这种情况下线程的原因是如此之慢是由于GIL和上下文切换。 –

回答

2

您的两个问题可以通过这个摘自docs回答:

由CPython的解释中所使用的机制,以确保只有一个线程同时执行Python的字节码这简化了。 CPython实现通过使对象模型(包括像dict这样的关键内置类型)隐式地避免并发访问。锁定整个解释器使得解释器更易于多线程化,但牺牲了大部分的并行性通过多处理器机器。

大胆强调我的。你最终花了很多时间在线程之间切换,以确保它们全部运行完成。这就像将一根绳子切成小块,然后再将其捆绑在一起,每次一根绳子。

由于每个进程都在其自己的地址空间中执行,所以使用多处理模块的结果与预期一致。这些过程彼此独立,除了处于同一个过程组并具有相同的父过程之外。