以下代码比较了多线程、多进程和普通顺序执行所耗费的时间:
import multiprocessing as mp import threading import time def job(): a = 0 for i in range(10000): for j in range(10000): a += 1 def by_multiprocess(): process1 = mp.Process(target=job) process2 = mp.Process(target=job) process1.start() process2.start() process1.join() process2.join() def by_multithread(): thread1 = threading.Thread(target=job) thread2 = threading.Thread(target=job) thread1.start() thread2.start() thread1.join() thread2.join() def by_non(): a = 0 for k in range(2): for i in range(10000): for j in range(10000): a += 1 if __name__ == '__main__': time_begin = time.time() by_multiprocess() time_finish = time.time() print('time of multiprocess =', time_finish - time_begin) time_begin = time.time() by_non() time_finish = time.time() print('time of non =', time_finish - time_begin) time_begin = time.time() by_multithread() time_finish = time.time() print('time of multithread =', time_finish - time_begin)
输出结果:
time of multiprocess = 4.632150888442993 time of non = 8.940110445022583 time of multithread = 8.282327890396118
从结果来看,多进程所花费的时间少于另外两种方式,而多线程与普通顺序执行相差不大。
这是因为程序实际运行时,多线程每个时间点只有一个线程在运行,例如thread1和thread2,虽然我们使用start让它们看起来都开始运行,事实上只有thread1在运行,只有当thread1遇到特殊情况如输入输出,需要暂停时,thread2才会开始运行,简而言之,一方停滞,另一方运行。所以有时从多线程展示给我们的输出结果来看,几个线程是同时进行的,而实质上,他们并不是同时进行。多线程只比普通顺序执行节省了停滞的时间。
另一方面多进程是真正的同时进行,因为每个进程具有独立的资源。
进行比较时,上文把循环2*10000*10000次当成一个任务,循环这么多次,就是为了增大计算量,得到比较大的运行时间,便于比较。那为什么不可以直接使用time.sleep命令增加运行时间?
以下代码使用time.sleep命令增加任务运行时间:
import multiprocessing as mp import threading import time def job(): for i in range(10): time.sleep(0.5) def by_multiprocess(): process1 = mp.Process(target=job) process2 = mp.Process(target=job) process1.start() process2.start() process1.join() process2.join() def by_multithread(): thread1 = threading.Thread(target=job) thread2 = threading.Thread(target=job) thread1.start() thread2.start() thread1.join() thread2.join() def by_non(): for k in range(2): for i in range(10): time.sleep(0.5) if __name__ == '__main__': time_begin = time.time() by_multiprocess() time_finish = time.time() print('time of multiprocess =', time_finish - time_begin) time_begin = time.time() by_non() time_finish = time.time() print('time of non =', time_finish - time_begin) time_begin = time.time() by_multithread() time_finish = time.time() print('time of multithread =', time_finish - time_begin)
输出结果:
time of multiprocess = 5.157954931259155 time of non = 10.155349731445312 time of multithread = 5.049519300460815
这次结果中普通顺序执行依旧耗时最长,而多线程花费的时间与多进程相差无几。
这是因为使用time.sleep时,线程是停滞状态,可以切换到另一个线程运行。虽然多进程有并行的优势,多线程在这个环境下用插空的方式减少了大量运行时间,使他们运行时间十分接近。
进程的建立会花费更多时间,所以在程序遇到大量停滞的情况时,或许多线程是更好的选择。