Python协程
今天给大家介绍一下协程。
协程存在于线程之中,线程默认不会等待协程执行
协程使用的库是gevent
spawn:开启协程(第一个参数为协程要执行的任务)
join: 让线程等待协程执行
协程之间切换的条件:gevent.sleep() 协程耗时等待的情况下才会切换
协程只能并发不能做并行
import gevent from gevent import monkey import time a = monkey.patch_all() def work_1(): for i in range(10): print("work1---{}".format(i)) # gevent.sleep(1) # 协程耗时等待的情况下才会切换 time.sleep(0.1) # gevent 的程序补丁 只要代码中有耗时的操作就会进行一个切换 monkey.patch_all() def work_2(): for i in range(10): print("work2---{}".format(i)) # gevent.sleep(1) # 协程耗时等待的情况下才会切换 time.sleep(0.1) monkey.patch_all() # 创建两个协程 g1 = gevent.spawn(work_1) g2 = gevent.spawn(work_2) g1.join() # 让线程等待协程执行 g2.join() # 让线程等待协程执行
下面附上一段代码,使用协程访问一个网站,利用队列加入访问的url地址,使用协程取出并访问
import requests
import gevent
from gevent import monkey
import queue
import time
count = 0
q = queue.Queue()
for i in range(1000):
q.put('http://localhost:3000/login')
def get():
global count
while q.qsize() > 0:
requests.get(url=q.get())
if q.qsize() == 0:
break
monkey.patch_all()
# count += 1
# print(count)
s = time.time()
g1 = gevent.spawn(get)
g2 = gevent.spawn(get)
g1.join()
g2.join()
e = time.time()
print(e - s)
前面有讲到进程、线程,今天又讲到了协程,那么该怎么结合使用呢
from threading import Thread
from multiprocessing import Process, Queue
import gevent
import requests
def work():
q = Queue()
for i in range(10000):
q.put('http://localhost:3000/')
print('{}个任务'.format(q.qsize()))
pro_list = []
for i in range(2):
# 创建2个进程 进程的工作函数process_work
p = Process(target=process_work, args=(q,))
p.start()
pro_list.append(p)
for p in pro_list:
p.join()
def process_work(q):
'''
:paran: q:进程中通讯的任务队列
'''
thread_list = []
# 在每一个进程中创建3个线程
for i in range(3):
# 线程的工作函数 thread_work
t = Thread(target=thread_work, args=(q,))
thread_list.append(t)
t.start()
for t in thread_list:
t.join()
def thread_work(q):
g_list = []
# 在每一个线程中创建5个协程
for i in range(5):
t = gevent.spawn(green_work, q, )
g_list.append(t)
gevent.joinall(g_list)
def green_work(q):
count = 0
# 判断队列内是否有值
while not q.empty():
# 设置超时等待时间
requests.get(url=q.get(0.01))
# 设置强制等待切换协程
gevent.sleep(0.001)
count += 1
print('协程执行了{}个任务'.format(count))
if __name__ == '__main__':
work()