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