问题:由于python使用“ GIL”,python是否能够同时运行其单独的线程?
信息:
看完这篇文章后,我对python是否能够利用多核处理器的不确定性产生了怀疑。尽管python做得很好,但认为它缺乏如此强大的功能实在是很奇怪。因此,我感到不确定,因此决定在这里提问。如果我编写的程序是多线程的,那么它是否可以在多个内核上同时执行?
问题:由于python使用“ GIL”,python是否能够同时运行其单独的线程?
信息:
看完这篇文章后,我对python是否能够利用多核处理器的不确定性产生了怀疑。尽管python做得很好,但认为它缺乏如此强大的功能实在是很奇怪。因此,我感到不确定,因此决定在这里提问。如果我编写的程序是多线程的,那么它是否可以在多个内核上同时执行?
Answers:
答案是“是,但是...”
但是当您使用常规线程进行并发时,cPython不能。
您可以使用或之类的东西multiprocessing
,celery
也mpi4py
可以将并行工作拆分为另一个进程。
或者,您可以使用Jython或IronPython之类的东西来使用没有GIL的替代解释器。
较软的解决方案是使用不会在GIL上运行的库来执行繁重的CPU任务,例如numpy
可以在不保留GIL的情况下进行繁重的工作,因此可以继续使用其他python线程。您也可以通过ctypes
这种方式使用库。
如果您不进行CPU限制工作,则可以完全忽略GIL问题(因为),因为python在等待IO时不会获取GIL。
Python线程无法利用许多内核。这是由于在python(cPython)的C实现中称为GIL(全局解释器锁)的内部实现细节,几乎可以肯定是您所使用的。
解决方法是为此目的开发的multiprocessing
模块http://www.python.org/dev/peps/pep-0371/。
文档:http : //docs.python.org/library/multiprocessing.html
(或使用并行语言。)
示例代码在我的ubuntu 14.04,python 2.7 64位上采用了所有4个内核。
import time
import threading
def t():
with open('/dev/urandom') as f:
for x in xrange(100):
f.read(4 * 65535)
if __name__ == '__main__':
start_time = time.time()
t()
t()
t()
t()
print "Sequential run time: %.2f seconds" % (time.time() - start_time)
start_time = time.time()
t1 = threading.Thread(target=t)
t2 = threading.Thread(target=t)
t3 = threading.Thread(target=t)
t4 = threading.Thread(target=t)
t1.start()
t2.start()
t3.start()
t4.start()
t1.join()
t2.join()
t3.join()
t4.join()
print "Parallel run time: %.2f seconds" % (time.time() - start_time)
结果:
$ python 1.py
Sequential run time: 3.69 seconds
Parallel run time: 4.82 seconds
我将脚本转换为Python3并在Raspberry Pi 3B +上运行:
import time
import threading
def t():
with open('/dev/urandom', 'rb') as f:
for x in range(100):
f.read(4 * 65535)
if __name__ == '__main__':
start_time = time.time()
t()
t()
t()
t()
print("Sequential run time: %.2f seconds" % (time.time() - start_time))
start_time = time.time()
t1 = threading.Thread(target=t)
t2 = threading.Thread(target=t)
t3 = threading.Thread(target=t)
t4 = threading.Thread(target=t)
t1.start()
t2.start()
t3.start()
t4.start()
t1.join()
t2.join()
t3.join()
t4.join()
print("Parallel run time: %.2f seconds" % (time.time() - start_time))
python3 t.py
Sequential run time: 2.10 seconds
Parallel run time: 1.41 seconds
对我来说,并行运行更快。