1. 程式人生 > 其它 >C語言基礎2

C語言基礎2

技術標籤:Python基礎筆記python

Python協程

大拿老師的Python筆記

1、協程基本用法

協程是為非搶佔式多工產生子程式的計算機程式元件,協程允許不同入口點在不同位置暫停或開始執行程式

從技術角度講,協程就是一個可以暫停執行的函式,或者乾脆把協程理解成生成器

協程的使用:yield返回,send呼叫

def simple_coroutine():
    print("->start")
    x = yield
    print("received"
, x) sc = simple_coroutine() print(1111) # 可以使用sc.send(None),效果一樣 next(sc) # 預激,即開始執行協程 # 會報錯
def simple_coroutine(a):
    print('->start')

    b = yield a
    print('->received', a, b)

    c = yield a + b
    print('->received', a, b, c)


sc = simple_coroutine(5)  # a = 5

aa = next
(sc) # 預激 , 開始執行 , 打印出 ->start , 返回a的值 print(aa) # 列印5 bb = sc.send(6) # 6就給了b , 打印出 ->received 5 6 , 同時返回 a + b print(bb) # 打印出a + b的值 , 即11 cc = sc.send(7) # 7就給了c , 打印出 ->received 5 6 7 print(cc)

協程終止:協程中未處理的異常會向上冒泡,傳給next函式或send方法的呼叫方(即觸發協程的物件)

協程終止的一種方式:傳送某個哨符值,讓協程退出。內建的None和Ellipsis等常量經常用作哨符值==。

yield from:

1.呼叫協程為了為了得到返回值,協程必須正常終止
2.生成器正常終止會發出StopIteration的異常,異常物件的value屬性儲存返回值
3.yield from從內部捕獲StopIteration異常(在最後面用yield返回一個值就不會報錯)
4.yield from可以呼叫生成器

二、協程高階用法-asyncio

asyncio本身是一個訊息迴圈

步驟

1.建立訊息迴圈
2.把協程匯入
3.關閉

import threading
import asyncio


async def hello(a):  # 這樣定義的就相當於一個協程任務
    print(a, threading.currentThread())
    await asyncio.sleep(5)
    print(a, threading.currentThread())


loop = asyncio.get_event_loop()  # 建立訊息迴圈
tasks = [hello("1"), hello("2")]  # 任務
loop.run_until_complete(asyncio.wait(tasks))  # 執行並等待任務完成
loop.close()  # 關閉迴圈

1.asyncio實現單執行緒的併發io , 在客戶端用處不大

2.在伺服器端可以asyncio + coroutine配合 , 因為http是io操作

3.asyncio實現了tcp, udp, ssl等協議

4.aiohttp是給予asyncio實現的http框架

5.pip install aiohttp安裝

三、concurrent.futures

類似其他語言的執行緒池的概念

利用multiprocessing實現真正的平行計算

核心原理:以子程序的形式,並行執行多個python直譯器

由於子程序與主直譯器相分離,所以他們的全域性直譯器鎖也是相互獨立的,每個子程序都完整使用一個CPU核心

concurre.futures.Executor

--ThreadPoolExeutor
--ProcessPoolExecutor
--執行的時候需要自行選擇

submit(fn, args, kwargs)

--fn : 非同步執行的函式
--args, kwargs : 引數
# 關於concurrent的案例
from concurrent.futures import ThreadPoolExecutor
import time


def return_future(msg):
    time.sleep(3)
    return msg


# 建立一個執行緒池
pool = ThreadPoolExecutor(2)  # 建立一個多大的執行緒池

# 往執行緒池加入兩個task 加入之後就會執行
f1 = pool.submit(return_future, 'hello')
f2 = pool.submit(return_future, 'world')


# done表示是否執行完畢
print(f1.done())
time.sleep(3)
print(f2.done())



# 返回結果
print(f1.result())
print(f2.result())

concurrent中的map函式

map(fn, *iterales, timeout=None)

跟map函式類似

函式需要非同步執行

timeout : 超時時間

# map案例
import time
import os
from concurrent import futures


data = ['1', '2']


def wait_on(argument):
    print(argument)
    time.sleep(2)
    return "OK"


ex = futures.ThreadPoolExecutor(2)  # 執行緒池
for i in ex.map(wait_on, data):  # 對映
    print(i)

futures及其他參考

一篇文章瞭解Python中的協程、例子、協程的發展

python多工—協程(一)