python 協程之特別篇

2022-03-09 18:14:45 字數 1789 閱讀 6120

python通過yield提供了對協程的基本支援,但是不完全。而第三方的gevent為python提供了比較完善的協程支援。

gevent是第三方庫,通過greenlet實現協程,其基本思想是:

當乙個greenlet遇到io操作時,比如訪問網路,就自動切換到其他的greenlet,等到io操作完成,再在適當的時候切換回來繼續執行。由於io操作非常耗時,經常使程式處於等待狀態,有了gevent為我們自動切換協程,就保證總有greenlet在執行,而不是等待io。

由於切換是在io操作時自動完成,所以gevent需要修改python自帶的一些標準庫,這一過程在啟動時通過monkey patch完成:

1、gevent協程適合i/o密集,不適合cpu密集。

3、gevent協程無法發揮多核優勢,事實上,協程只是以單執行緒的方式在執行。

3、子程式就是協程的一種特例

# -*- 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 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()

Python之路 特別篇 Python切片

切片操作符是序列名後跟乙個方括號,方括號中有一對可選的數字,並用冒號分割。注意 數是可選的,而冒號是必須的。consequence start end step 切片操作符中的第乙個數 冒號之前 表示切片開始的位置,第二個數 冒號之後 表示切片到 結束,第三個數 冒號之後 表示切片間隔數。如果不指定...

Python之路 特別篇 Python反射

說反射之前先介紹一下 import 方法,這個和import匯入模組的另一種方式 1.import commons 2.import commons 如果是多層匯入 1.from list.text import commons 2.import list.text.commons fromlist...

小猿日記(5) 520特別篇

今天就不聊啥工作,啥日常了。工作 敲鍵盤 日常 睡大覺 健身 早上吃大豆包子,喝著紅豆鮮奶。手敲鍵盤,眼觀螢幕,心繫佳人。遇見了你 星星開始閃爍 陽光也是橙子的芬香 微風輕撫 想象是與你遊覽春光 聽自然的妙不可言 徜徉於原野之間嬉笑 因為是你 我看見了未來 那是在你眼中 我才看見了自己的美麗 無聲無...