目录
4.协程节约的时间的大小,取决于任务的IO耗时操作多不多,若IO操作多,协程越多,越省时。
进程,线程,协程的通俗描述:
有一个老板想要开个工厂进行生产某件商品
他需要一些财力和物力制作一条生产线,这条生产线上所有的材料资源和器具资源都是为了能够生产商品而准备的, 这些资源称之为:进程。
只有生产线上不能够生产商品的,还得找工人来进行生产,这些工人能够利用这些材料将商品一步步地生产出来,这些来做事情的工人称之为:线程。
老板为了提高生产效率,想到了3中办法:
1.在这条生产线上多招些工人,一起来做商品,这样效率时成倍增长,即单进程 多线程方式。
2.老板发现这条生产线上的工人不是越多越好,因为一条生产线上的材料和器具资源毕竟有限,所以老板又花了些财力和物力购置了另外一条生产线,然后在新生产线上的招些工人,这样效率又进一步提高了,即多进程 多线程方式。
3.老板发现,现在已经有了多条生产线,并且每条生产线上已经有很多工人了(多进程 多线程模式),为了再次提高效率,老板想了个损招规定:如果员工在上班时间临时没事或者在等待某些条件(比如等待另一个工人生产完某道工序之后,他才能再次工作),那么这个员工就利用这些时间去做其他的工作,也就是说:如果一个线程等待某些条件,可以利用这些时间去做其他的事情,即:多进程 协程方式。
总结:
1.进程说资源分配的单位,线程数cpu调度的单位。
2.进程切换需要的资源最大,效率最低;线程切换需要的资源一般,效率也一般(在不考虑GIL锁的情况下);协程切换需要的资源最小,效率最高。
3.多进程,多线程根据cpu核数不一样可能是并行的,但是协程说在一个线程中,所以是并发;python中的线程由于GIL锁的存在,并不能实现并行。
1.多线程:10000个任务,3个线程耗时:9.669秒
"""
多线程与多进程的速度对比:
比较10000个任务,分别使用3个线程与3个进程来完成,比较哪种方式更快。
"""
import requests
"1.多线程"
import threading, time, os, queue
# 线程的队列(只能在一个进程中使用,解决多线程之间的通信问题)
q1 = queue.Queue()
for i in range(10000):
q1.put("http://127.0.0.1:5000")
def work():
while q1.qsize() > 0:
url = q1.get()
requests.get(url=url)
def main():
st = time.time()
t1 = threading.Thread(target=work)
t2 = threading.Thread(target=work)
t3 = threading.Thread(target=work)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
et = time.time()
print("10000个任务,多线程耗时{}".format(et - st))
if __name__ == '__main__':
main()
输出:
# 10000个任务,多线程耗时9.669008731842041
2.多进程:10000个任务,3个进程耗时:7.311秒
"""
多线程与多进程的速度对比:
比较1000个任务,分别使用3个线程与3个进程来完成,比较哪种方式更快。
"""
"3.进程池"
import requests, time, os
from multiprocessing import Pool, Manager
# 进程池中的队列(可以给进程池中的各个进程之间使用)
i = 0
def work(q3):
while q3.qsize() > 0:
url = q3.get()
requests.get(url=url)
global i
i += 1
print(" {}进程运行了:{}次".format(os.getpid(), i))
def main():
q3 = Manager().Queue()
for i in range(10000):
q3.put("http://127.0.0.1:5000")
st = time.time()
pool = Pool(3) # 进程池中创建3个进程。
for i in range(3):
# 创建3个进程执行任务(10000个任务)。
pool.apply_async(func=work, args=(q3,))
# 关闭进程池
pool.close()
# 主进程等待进程池中所有子进程执行完毕
pool.join()
et = time.time()
print("10000个任务,多进程耗时{}".format(et - st)) # 10000个任务,多进程耗时11.982725858688354
if __name__ == '__main__':
main()
输出:
30403进程运行了:3334次
30402进程运行了:3325次
30401进程运行了:3341次
10000个任务,多进程耗时7.311042070388794
3.协程:10000个任务,1个线程耗时:17.382秒
"""
多线程与多进程,协程的速度对比:
比较1000个任务,分别使用1个线程和3个协程来完成,比较哪种方式更快。
"""
import gevent
import requests, os, time, queue
from gevent import monkey
"4.协程"
monkey.patch_all()
def work(q4):
while q4.qsize() > 0:
url = q4.get()
requests.get(url=url)
def main():
q4 = queue.Queue()
for i in range(10000):
q4.put("http://127.0.0.1:5000")
st = time.time()
# 创建1个线程
work(q4)
et = time.time()
print("10000个任务,1个线程耗时{}".format(et - st))
if __name__ == '__main__':
main()
输出:
10000个任务,1个线程耗时17.38252019882202
4.协程:10000个任务,3个协程耗时:12.768秒
"""
多线程与多进程,协程的速度对比:
比较1000个任务,分别使用3个线程与3个进程和3个协程来完成,比较哪种方式更快。
"""
import gevent
import requests, os, time, queue
from gevent import monkey
"4.协程"
monkey.patch_all()
def work(q4):
while q4.qsize() > 0:
url = q4.get()
requests.get(url=url)
def main():
q4 = queue.Queue()
for i in range(10000):
q4.put("http://127.0.0.1:5000")
st = time.time()
# 创建3个协程
gevent.joinall([gevent.spawn(work, q4),gevent.spawn(work, q4),gevent.spawn(work, q4)])
# g1 = gevent.spawn(work, q4)
# g2 = gevent.spawn(work, q4)
# g3 = gevent.spawn(work, q4)
# g1.join()
# g2.join()
# g3.join()
et = time.time()
print("10000个任务,协程耗时{}".format(et - st))
if __name__ == '__main__':
main()
输出:
10000个任务,协程耗时12.768423080444336
5.3个协程跑1000个任务,耗时:34.68秒
"""
,协程的速度对比:
比较1000个任务,分别使用3个和6个协程来完成,比较哪种方式更快。
"""
import gevent
import time, queue
from gevent import monkey
"4.协程"
monkey.patch_all()
def work(q4):
while q4.qsize() > 0:
url = q4.get()
time.sleep(0.1)
def main():
q4 = queue.Queue()
for i in range(1000):
q4.put(i)
st = time.time()
g_list = []
for i in range(3):
g_list.append(gevent.spawn(work, q4))
# 创建3个协程
gevent.joinall(g_list)
et = time.time()
print("1000个任务,协程耗时{}".format(et - st))
if __name__ == '__main__':
main()
输出:
1000个任务,协程耗时34.68190383911133
6. 6个协程跑1000个任务,耗时:17.356秒
"""
,协程的速度对比:
比较1000个任务,分别使用3个和6个协程来完成,比较哪种方式更快。
"""
import gevent
import time, queue
from gevent import monkey
"4.协程"
monkey.patch_all()
def work(q4):
while q4.qsize() > 0:
url = q4.get()
time.sleep(0.1)
def main():
q4 = queue.Queue()
for i in range(1000):
q4.put(i)
st = time.time()
g_list = []
for i in range(6):
g_list.append(gevent.spawn(work, q4))
# 创建3个协程
gevent.joinall(g_list)
et = time.time()
print("1000个任务,协程耗时{}".format(et - st))
if __name__ == '__main__':
main()
输出:
10000个任务,协程耗时17.356290102005005