协程:可以暂定并切换到其他协程运行的函数
线程是由操作系统调度
协程的调度是由程序员实现
生成器暂停函数举例
import time
# 普通函数无法暂停
def add(a, b):
print(a+b)
# 生成器是可以暂停函数的
def yield_test():
yield 1
yield 2
yield 3
return "bobby"
my_yield = yield_test()
for item in my_yield:
print(item)
print('休息1s')
time.sleep(1)
将生成器装饰为协程
from tornado.gen import coroutine
# 定义的方式一
@coroutine
def yield_test():
yield 1
yield 2
yield 3
return "bobby"
my_yield = yield_test()
for item in my_yield:
print(item)
采用async关键字定义协程
# yield from只能用户coroutine写的方法,使用async时采用await
# 方式二,使用async关键字,推荐采用async,别用coroutine
async def yield_test1():
yield 1
yield 2
yield 3
async def yield_test2():
yield 4
yield 5
yield 6
# 协程的对象要运行起来就要用await方法
# 有多个协程对象时,切换和调度协程也是用到await
async def main1():
result = await yield_test1()
result = await yield_test2()
async def main2():
await yield_test1()
httpclient的使用
这个是同步的,用处不大,不如直接用requests包
from tornado import httpclient
http_client = httpclient.HTTPClient()
try:
response = http_client.fetch("http://www.tornadoweb.org/en/stable/")
print(response.body)
except httpclient.HTTPError as e:
# HTTPError is raised for non-200 responses; the response
# can be found in e.response.
print("Error: " + str(e))
except Exception as e:
# Other errors are possible, such as IOError.
print("Error: " + str(e))
http_client.close()
事件循环和协程实现 的示例代码
AsyncHTTPClient区别与httpclient,是采用的异步的方式
from tornado.httpclient import AsyncHTTPClient
async def f():
http_client = AsyncHTTPClient()
try:
response = await http_client.fetch(
"http://www.tornadoweb.org/en/stable/")
except Exception as e:
print("Error: %s" % e)
else:
print(response.body.decode("utf8"))
if __name__ == '__main__':
import tornado
io_loop = tornado.ioloop.IOLoop.current() # 启动事件循环 他是单例 全局唯一的
# run_sync可以在运行完某个协程后停止事件循环
io_loop.run_sync(f)
持续运行的写法
if __name__ == '__main__':
# import tornado
# io_loop = tornado.ioloop.IOLoop.current()
# # # run_sync可以在运行完某个协程后停止事件循环
# # io_loop.run_sync(f)
#
# 可以采用这种方式 使程序持续运行
import asyncio
asyncio.ensure_future(f())
asyncio.get_event_loop().run_forever()
另一种写法
if __name__ == '__main__':
import asyncio
asyncio.get_event_loop().run_until_complete(f())