python网络编程–协程
gevent三方模块
好处是:使用简单
缺点是:不能使用框架
import gevent # 导入三方模块包
from gevent import monkey # 导入gevent模块的monkey方法
monkey.patch_all() # 把其它模块变为自己的模块来使用,比如time
import time
def func1():
print('start func1')
time.sleep(1)
print('end func1')
def func2():
print('start func2')
time.sleep(1)
print('end func2')
g1 = gevent.spawn(func1) # 创建一个协程任务
g2 = gevent.spawn(func2) # 创建一个协程任务
g1.join() # 阻塞 直到g1任务完成为止
g2.join() # 阻塞 直到g2任务完成为止
joinall用法
import gevent
from gevent import monkey # 导入gevent模块的monkey方法
monkey.patch_all() # 把其它模块变为自己的模块来使用,比如time
import time
def func1():
print('start func1')
time.sleep(1)
print('end func1')
def func2():
print('start func2')
time.sleep(1)
print('end func2')
g1 = gevent.spawn(func1) # 创建一个协程任务
g2 = gevent.spawn(func2) # 创建一个协程任务
# g1.join() # 阻塞 直到g1任务完成为止
# g2.join() # 阻塞 直到g2任务完成为止
gevent.joinall([g1,g2]) #等同于上面两句话,传入的任务参数需要为列表形式
循环创建协程
import gevent
from gevent import monkey # 导入gevent模块的monkey方法
monkey.patch_all() # 把其它模块变为自己的模块来使用,比如time
import time
def func1(i):
print('start func1 : %s'%i)
time.sleep(1)
print('end func1 : %s'%i)
g_l = []
for i in range(10):
g = gevent.spawn(func1,i) # 第一个参数为函数名,其余为 *args,**kwargs
g_l.append(g)
gevent.joinall(g_l)
有返回值
import gevent
from gevent import monkey # 导入gevent模块的monkey方法
monkey.patch_all() # 把其它模块变为自己的模块来使用,比如time
import time
def func1(i):
print('start func1 : %s'%i)
time.sleep(1)
print('end func1 : %s'%i)
return i
g_l = []
for i in range(10):
g = gevent.spawn(func1,i) # 第一个参数为函数名,其余为 *args,**kwargs
g_l.append(g)
gevent.joinall(g_l)
for i in g_l:
print(i.value) # 取值为 对象.value,相当于 g.value
asyncio内置模块
好处是:可以应用到爬虫、web框架、提高网络编程的效率和并发效果
缺点是:越接近底层写起来越复杂
# 语法
# await 阻塞 协程函数这里要切换出去,还能保证一会儿再切回来
# await 必须写在async函数里,async函数是协程函数
# loop 事件循环
# 所有的协程的执行 调度 都离不开这个loop
import asyncio
async def func(): # 协程方法
print('start')
await asyncio.sleep(1) # 阻塞
print('end')
loop = asyncio.get_event_loop() # 创建一个事件循环
loop.run_until_complete(func()) # 把func任务丢到事件循环中去执行
启动多个任务,没有返回值
import asyncio
# 启动多个任务,并且没有返回值
async def demo(): # 协程方法
print('start')
await asyncio.sleep(1) # 阻塞
print('end')
loop = asyncio.get_event_loop() # 创建一个事件循环
wait_obj = asyncio.wait([demo(),demo(),demo()])
loop.run_until_complete(wait_obj)
启动多个任务,有返回值
import asyncio
# 启动多个任务并且有返回值
async def demo(): # 协程方法
print('start')
await asyncio.sleep(1) # 阻塞
print('end')
return 123
loop = asyncio.get_event_loop() # 创建一个事件循环
t1 = loop.create_task(demo())
t2 = loop.create_task(demo())
tasks = [t1,t2]
wait_obj = asyncio.wait([t1,t2])
loop.run_until_complete(wait_obj) # 把 任务对象 丢到事件循环中去执行
for t in tasks:
print(t.result())
谁先回来先取谁的结果
# 谁先回来先取谁的结果
import asyncio
async def demo(i): # 协程方法
print('start')
await asyncio.sleep(10-i) # 阻塞
print('end')
return i,123
async def main():
task_l = []
for i in range(10):
task = asyncio.ensure_future(demo(i))
task_l.append(task)
for ret in asyncio.as_completed(task_l):
res = await ret
print(res)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())