您好我正在尝试计算前10000个素数。
我首先执行非线程,然后将计算分为1到5000和5001到10000.我预计线程的使用会使它显着更快,但输出是这样的:
--------Results--------
Non threaded Duration: 0.012244000000000005 seconds
Threaded Duration: 0.012839000000000017 seconds
实际上没有什么大不同,只是螺纹功能甚至有点慢。
有什么问题?
这是我的代码:
import math
from threading import Thread
def nonThreaded():
primeNtoM(1,10000)
def threaded():
t1 = Thread(target=primeNtoM, args=(1,5000))
t2 = Thread(target=primeNtoM, args=(5001,10000))
t1.start()
t2.start()
t1.join()
t2.join()
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
for i in range(3, int(math.sqrt(n)) + 1, 2):
if n % i == 0:
return False
return True
def primeNtoM(n,m):
L = list()
if (n > m):
print("n should be smaller than m")
return
for i in range(n,m):
if(is_prime(i)):
L.append(i)
if __name__ == '__main__':
import time
print("--------Nonthreaded calculation--------")
nTstart_time = time.clock()
nonThreaded()
nonThreadedTime = time.clock() - nTstart_time
print("--------Threaded calculation--------")
Tstart_time = time.clock()
threaded()
threadedTime = time.clock() - Tstart_time
print("--------Results--------")
print ("Non threaded Duration: ",nonThreadedTime, "seconds")
print ("Threaded Duration: ",threadedTime, "seconds")
答案 0 :(得分:11)
来自:https://wiki.python.org/moin/GlobalInterpreterLock
在CPython中,全局解释器锁或GIL是一个互斥锁,它可以防止多个本机线程一次执行Python字节码。这种锁是必要的,主要是因为CPython的内存管理不是线程安全的。 (但是,由于存在GIL,其他功能已经增长,取决于它所强制执行的保证。)
这意味着:由于这是CPU密集型的,并且python不是线程安全的,因此它不允许您在同一进程中一次运行多个字节码。所以,你的线程互相交替,转换开销就是额外的时间。
答案 1 :(得分:4)
您可以使用multiprocessing模块,其结果如下:
('Non threaded Duration: ', 0.016599999999999997, 'seconds')
('Threaded Duration: ', 0.007172000000000005, 'seconds')
...在对代码进行这些更改后(将“Thread”更改为“Process”):
import math
#from threading import Thread
from multiprocessing import Process
def nonThreaded():
primeNtoM(1,10000)
def threaded():
#t1 = Thread(target=primeNtoM, args=(1,5000))
#t2 = Thread(target=primeNtoM, args=(5001,10000))
t1 = Process(target=primeNtoM, args=(1,5000))
t2 = Process(target=primeNtoM, args=(5001,10000))
t1.start()
t2.start()
t1.join()
t2.join()
通过产生实际的操作系统进程而不是使用进程内线程,您可以消除@Luis Masuelli回答中讨论的GIL问题。
multiprocessing是一个使用a支持产生进程的包 API类似于线程模块。多处理包 提供本地和远程并发,有效地侧面步进 全局解释器锁通过使用子进程而不是线程。 因此,多处理模块允许程序员完全 利用给定计算机上的多个处理器。它可以在Unix上运行 和Windows。