Python經過yield提供了對協程的基本支持,可是不徹底。而第三方的gevent爲Python提供了比較完善的協程支持。
gevent是第三方庫,經過greenlet實現協程,其基本思想是:
當一個greenlet遇到IO操做時,好比訪問網絡,就自動切換到其餘的greenlet,等到IO操做完成,再在適當的時候切換回來繼續執行。因爲IO操做很是耗時,常常使程序處於等待狀態,有了gevent爲咱們自動切換協程,就保證總有greenlet在運行,而不是等待IO。
因爲切換是在IO操做時自動完成,因此gevent須要修改Python自帶的一些標準庫,這一過程在啓動時經過monkey patch完成:
一、gevent協程適合I/O密集,不適合CPU密集。
三、gevent協程沒法發揮多核優點,事實上,協程只是以單線程的方式在運行。
三、子程序就是協程的一種特例
從下面例子入道, 單線程 函數級 切換任務執行,支持大量併發, 而 線程 以及 進程都是內核級別的
# -*- coding: utf-8 -*-
__author__ = 'Frank Li'
import asyncio
from functools import wraps
import time
def time_count(func):
@wraps(func)
def inner_func(*args,**kw):
start = time.time()
result = func(*args,**kw)
end = time.time()
print('{} cost {:.1f} s totally'.format(func.__name__,(end-start)))
return result
return inner_func
@asyncio.coroutine
def task_io_1():
print('{} started...'.format(task_io_1.__name__))
# 假設這裏 io 任務須要耗費 2s 時間
yield from asyncio.sleep(3)
print('在我以前,由於 io 異步了,那麼久中斷去執行另外的任務了,等執行完又來執行我了,{} continue...'.format(task_io_1.__name__))
return task_io_1.__name__
async def do_some_io_workd(n):
asyncio.sleep(n)
@asyncio.coroutine
def task_io_2():
print('{} start...'.format(task_io_2.__name__))
yield from asyncio.sleep(5)
print('在我以前,由於 io 異步了,那麼久中斷去執行另外的任務了,等執行完又來執行我了,{} continue...'.format(task_io_2.__name__))
return task_io_2.__name__
@time_count
def main():
tasks = [task_io_1(),task_io_2()]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
if __name__ == '__main__':
main()
![](http://static.javashuo.com/static/loading.gif)