协程
微线程,纤程 -- Coroutine
子程序(函数) -- 所有语言中都是层级调用,子程序调用是一通过栈实现的,一个线程就是执行一个子程序。
子程序调用是明确的,一个入口,一次返回。
协程看上去像子程序,但在执行过程中可中断。有点像执行多线程,但是它是一个线程执行。
协程比多线程的优势:极高的执行效率,没有线程切换的开销;没有线程的锁机制。
使用协程利用多CPU的方式:多进程+协程
python对协程的支持通过generator实现。
通过for迭代,不断调用next()函数获取由yield返回的下一个值。
python的yield不但可以返回一个值,还可以接收调用者发出的参数。
生产者消费者通过yield的实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
def
consumer():
r
=
''
while
True
:
n
=
yield
r
if
not
n:
return
print
(
'[CONSUMER] Consuming %s...'
%
n)
r
=
'200 OK'
def
produce(c):
c.send(
None
)
n
=
0
while
n <
5
:
n
=
n
+
1
print
(
'[PRODUCER] Producing %s...'
%
n)
r
=
c.send(n)
print
(
'[PRODUCER] Consumer return: %s'
%
r)
c.close()
c
=
consumer()
produce(c)
|
asyncio
asyncio的编程模型就是一个消息循环。
实现异步IO -- 从asyncio模块中获取一个eventloop的引用,然后把需要执行的协程扔到eventloop中执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import
asyncio
@asyncio
.coroutine
def
hello():
print
(
"hello, world!"
)
# 异步调用 asyncio.sleep(1)
r
=
yield
from
asyncio.sleep(
1
)
print
(
"hello again!"
)
# 获取eventloop
loop
=
asyncio.get_event_loop()
# 执行conroutine
loop.run_until_complete(hello())
loop.close()
|
async/await
async和await是针对coroutine的新语法,只需要做两部简单的替换。
-
把@asyncio.coroutine替换为async
-
把yield from 替换为await
1
2
3
4
|
async
def
hello():
print
(
"hello world!"
)
r
=
await asyncio.sleep(
1
)
print
(
"hello again!"
)
|
aiohttp
asyncio实现了TCP、UDP、SSL协议,aiohttp基于asyncio实现的http框架。
一个aiohttp实现的http服务器。分别处理以下URL:
/ -- 返回b'<h1>Index</h1>'
/hello/{name} -- 根据URL参数返回文本hello,%s!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import
asyncio
from
aiohttp
import
web
async
def
index(request):
await asyncio.sleep(
0.5
)
return
web.Response(body
=
b
'<h1>Index</h1>'
)
async
def
hello(request):
await asyncio.sleep(
0.5
)
text
=
'<h1>hello, %s!</h1>'
%
request.match_info[
'name'
]
return
web.Response(body
=
text.encode(
'utf-8'
))
async
def
init(loop):
app
=
web.Application(loop
=
loop)
app.router.add_route(
'GET'
,
'/'
, index)
app.router.add_route(
'GET'
,
'/hello/{name}'
, hello)
srv
=
await loop.create_server(app.make_handler(),
'127.0.0.1'
,
8000
)
print
('Server started at
return
srv
loop
=
asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()
|
本文转自ting2junshui51CTO博客,原文链接:http://blog.51cto.com/ting2junshui/1753737
,如需转载请自行联系原作者