想必对接触过python的朋友都知道,python的多线程由于历史原因有一个GIL,并不是真正的多线程。所以查了些许资料亲自跑了下程序比较了下。
测试环境
macbook pro, 双核四线程,i5处理器。
比较对象
单线程
# thread_test.py
import random
import threading
def list_append(count, id, out_list):
"""
Creates an empty list and then appends a
random number to the list 'count' number
of times. A CPU-heavy operation!
"""
for i in range(count):
out_list.append(random.random())
def main():
size = 10000000 # Number of random numbers to add
threads = 2 # Number of threads to create
# Create a list of jobs and then iterate through
# the number of threads appending each thread to
# the job list
# jobs = []
for i in range(0, threads):
out_list = list()
thread = threading.Thread(target=list_append(size, i, out_list))
thread.start()
thread.join()
if __name__ == "__main__":
main()
单线程执行两次list_append函数。
多线程
# thread_test.py
import random
import threading
def list_append(count, id, out_list):
"""
Creates an empty list and then appends a
random number to the list 'count' number
of times. A CPU-heavy operation!
"""
for i in range(count):
out_list.append(random.random())
def main():
size = 10000000 # Number of random numbers to add
threads = 2 # Number of threads to create
# Create a list of jobs and then iterate through
# the number of threads appending each thread to
# the job list
jobs = []
for i in range(0, threads):
out_list = list()
thread = threading.Thread(target=list_append(size, i, out_list))
jobs.append(thread)
# Start the threads (i.e. calculate the random number lists)
for j in jobs:
j.start()
# Ensure all of the threads have finished
for j in jobs:
j.join()
if __name__ == "__main__":
main()
开双线程执行同一个函数。
多进程
# multiproc_test.py
import random
import multiprocessing
def list_append(count, id, out_list):
"""
Creates an empty list and then appends a
random number to the list 'count' number
of times. A CPU-heavy operation!
"""
for i in range(count):
out_list.append(random.random())
def main():
size = 10000000 # Number of random numbers to add
procs = 2 # Number of processes to create
# Create a list of jobs and then iterate through
# the number of processes appending each process to
# the job list
jobs = []
for i in range(0, procs):
out_list = list()
process = multiprocessing.Process(target=list_append,
args=(size, i, out_list))
jobs.append(process)
# Start the processes (i.e. calculate the random number lists)
for j in jobs:
j.start()
# Ensure all of the processes have finished
for j in jobs:
j.join()
if __name__ == "__main__":
main()
开双进程执行同一个函数。
测试结果
$ time python single_thread_test.py
real 0m4.590s
user 0m4.082s
sys 0m0.448s
$ time python thread_test.py
real 0m4.426s
user 0m3.900s
sys 0m0.456s
$ time python process_test.py
real 0m2.436s
user 0m4.028s
sys 0m0.657s
测试程序用时用的是time指令,传送门在此可以自行学习。
可以从上面的测试结果看到,单线程与双线程在耗时方面并没有太多的区别,但是改为双进程后可以很明显的看到,耗时少了接近一半。这很好的说明了python多进程才是真正的并发。
当然python的多线程也不是一无是处,还是多线程有时相较于单线程还是有优势的,具体可以看这篇博客:传送门
参考文献:
https://www.quantstart.com/articles/parallelising-python-with-threading-and-multiprocessing
http://blog.csdn.net/thinkerabc/article/details/647272
http://www.redicecn.com/html/Python/20111223/355.html
http://python.jobbole.com/84205/