并行和并发
- 并行处理
是计算机系统中同时执行两个以上任务的一种执行方法。并行可同时工作同一程序的不同方面,并行处理的主要目的是节省大型和复杂问题的解决时间 - 并发处理
指同一时间段中有多个程序都处于已经运行到运行完毕之间,而且这多个程序都是在同一处理机(CPU)上运行,但任意时刻点上只有一个程序在CPU上运行
同步和异步
- 同步
指一个进程在执行某个请求时,若该请求遇到IO耗时,那么其他进程将会一直等待下去,直到遇到耗时的哪个进程执行结束返回结果,后面的进程才能继续执行下去 - 异步
指进程遇到耗时其他进程不需要一直等下去,而是执行自己的任务。
单进程
from random import randint
from time import time, sleep
def download_task(filename):
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
start = time()
download_task('Python入门.pdf')
download_task('av.avi')
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
结果
开始下载Python入门.pdf...
Python入门.pdf下载完成! 耗费了8秒
开始下载av.avi...
av.avi下载完成! 耗费了7秒
总共耗费了15.03秒.
运行是顺序执行,所以耗时是多个进程的时间总和
因为是单进程任务,所有任务都是排队进行所以这样执行效率非常的低。我们来添加多进程模式进行多进程同时执行,这样一个进程执行时,另一个进程无需等待,执行时间将大大缩短。
多进程
from random import randint
from time import time, sleep
from multiprocessing import Process
from os import getpid
def download_task(filename):
print('启动下载进程,进程号:[%d]'%getpid())
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
start = time()
p1 = Process(target=download_task,args=('python入门.pdf',))
p2 = Process(target=download_task,args=('av.avi',))
p1.start()
p2.start()
p1.join()
p2.join()
# download_task('Python入门.pdf')
# download_task('av.avi')
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()
多个进程并排执行,总耗时就是最长耗时的那个进程的时间。
多进程的特点是相互独立,不会共享全局变量,即在一个进程中对全局变量修改过后,不会影响另一个进程中的全局变量。
Queue 队列实现进程间通信
from random import randint
from time import time,sleep
from multiprocessing import Process
import multiprocessing
from os import getpid
time_to_download = 3
def write(q):
for i in ['python入门','av.avi','java入门']:
q.put(i)
print('启动写入进程,进程号:[%d]'%getpid())
print('开始写入%s...' % i)
sleep(time_to_download)
def read(q):
while True:
if not q.empty():
print('启动读取进程,进程号:[%d]'%getpid())
print('开始读取%s...' % q.get())
sleep(time_to_download)
else:
break
def main():
q = multiprocessing.Queue()
p1 = Process(target=write,args=(q,))
p2 = Process(target=read,args=(q,))
p1.start()
p1.join()
p2.start()
p2.join()
if __name__ == '__main__':
main()