2016-09-19 33 views
2

我想要使用线程在python中获得更好的性能。Python中的线程-

我的程序需要返回线程执行的每个函数的值。

而且我需要知道线程何时完成。

有3种方法我试图执行这个小程序。

import thread 
import datetime 
from threading import Thread 
import threading 
from multiprocessing.pool import ThreadPool 


def func1(word): 
    i=0 
    while i<100000: 
     if 1<2: 
      i=i+1 
    return "func1" 


def func2(): 
    i=0 
    while i<100000: 
     if 1<2: 
      i=i+1 
    return "func2" 

word="hiiii" 

""" 
#--------------------------------example1-------------------------------- 
pool = ThreadPool(processes=2) 

print str(datetime.datetime.now().time()) 
async_result1 = pool.apply_async(func1, (word,)) 

async_result2 = pool.apply_async(func2) 

print async_result1.get() 
print async_result2.get() 
print str(datetime.datetime.now().time()) 


print func1(word) 
print func2() 
print str(datetime.datetime.now().time()) 
#with threads-71000 
#without threads- 40000 
#--------------------------------example1-------------------------------- 
""" 

""" 
#--------------------------------example2-------------------------------- 

t1 = Thread(target=func1, args=(word,)) 
t2 = Thread(target=func2, args=()) 
print str(datetime.datetime.now().time()) 

t1.start() 
t2.start() 

t1.join() 
t2.join() 
print str(datetime.datetime.now().time()) 

func1(word) 
func2() 
print str(datetime.datetime.now().time()) 

#with threads-75000 
#without threads-42000 
#--------------------------------example2-------------------------------- 
""" 

""" 
#--------------------------------example3 without sending value-------------------------------- 
print str(datetime.datetime.now().time()) 

t1 = threading.Thread(name=func1,target=func1) 
t2= threading.Thread(name=func2,target=func2) 
t1.start() 
t2.start() 

t1.join() 
t2.join() 
print str(datetime.datetime.now().time()) 
func1() 
func2() 
print str(datetime.datetime.now().time()) 

#with threads- 73000 
#without threads- 42000 
#--------------------------------example3 without sending value------------- ------------------- 
    """ 

但是,你可以看到更好的运行方式是没有线程的! 为什么?我做错了什么?如何使用线程?

+1

线程通常只在任务是IO绑定时才有用;这段代码显然是CPU绑定的。 –

+0

GIL(全局解释器锁),python线程不是本地线程 –

回答

3

当你有多个任务争夺CPU时,线程主要用于处理,但大部分时间都花在等待网络读取或数据库写入等外部事件。

多线程处于活动状态时,它决定切换到另一个线程(假设还有其他可运行线程)花费的每个(某些数量)操作码。如果你的线程都没有做任何事情,除了计算,那么实际上没有时间通过​​在线程之间切换来节省。由于所有线程都在同一进程中运行,并且Python进程无法(通常)利用多个CPU,因此不会看到任何加速(实际上,可能由于线程切换活动而导致速度减慢)。

tl; dr:CPU绑定的任务不能通过多线程加速。

1

要追加对方回答:

原因线程版本实际上是CPU密集型操作慢是(如前所述)GIL,全局解释锁。 GIL作为一个互斥体,一次只允许一个线程访问它。所以线程只在等待IO操作时有用。

但是,有一种方法可以在多个内核中实际执行代码,绕过GIL的问题。解决方案是使用multiprocessing库。

所以你的情况:

process1 = multiprocessing.Process(target=func1, args=(word,)) 
process1.start() 
process2 = multiprocessing.Process(target=func2) 
process2.start() 

process.join() 
process2.join() 

两个过程应该在不同的内核启动,有效地使程序执行得更快。对我来说,它几乎减半执行时间。请注意,产生比核心更多的进程将再次使其运行速度变慢。