python學習筆記 day40 協程

2022-02-06 19:17:47 字數 4544 閱讀 2797

程序是cpu資源分配的最小單位; 執行緒是cpu排程的最小單位;

協程就是在乙個執行緒內切換執行任務;

之前使用yield也可以實現在乙個主線程中切換執行:

def func1():  #

生成器函式

print("

吃飯嗎"

)

yield

print("

那我們走吧")

yield

deffunc2():

g=func1() #

生成器函式在被呼叫時不會立即執行,除非next(g)觸發才可以

next(g) #

開始執行func1()函式,但是遇到yield就會停止

print("吃"

) next(g)

print("

好的,走吧")

func2()

使用yield實現生產者消費者模型;

import

random

import

time

def consumer(): #

消費者模型

while

true:

n=yield

#yield接收g.send()的結果,然後賦值給n

time.sleep(random.random())

print("

消費了%s

"%n)

def procuder(): #

生產者模型

g=consumer() #

呼叫生成器函式,並不會理解執行生成器函式內部的**(除非next()進行觸發)

next(g) #

開始執行生成器函式

for i in range(10):

print("

生產了%s

"%i)

g.send(i)

#send()給生成器函式yield處接收

procuder()

執行結果::

#切換執行func2()

print("

byte~ xuanxuan")

g2.switch()

deffunc2():

print("

hello,xixi")

g1.switch()

#切換執行func1()

print("

bye~")

g1=greenlet(func1)

g2=greenlet(func2)

g1.switch()

#切換執行func1

執行結果:

另外需要注意greenlet切換時是不規避io時間的:

from greenlet import

greenlet

import

time

deffunc1():

print("

func1:吃飯去嗎")

g2.switch()

time.sleep(2) #

greenlet進行切換時,並不會規避掉io時間(也就是切換回來時還是需要等待2秒在執行)

print("

func1:那我們走吧")

g2.switch()

deffunc2():

time.sleep(2)

print("

func2:吃")

g1.switch()

time.sleep(3)

print("

func2:好的")

g1=greenlet(func1)

g2=greenlet(func2)

g1.switch()

執行結果: 

如果在同乙個程式有io的情況下,才切換會讓效率提高很多,但是yield greenlet均不會在切換時規避掉io時間

其實就相當於原來func1需要等待3秒,但是如果不切換,順序執行,那麼func2也會跟著等待3秒,浪費了兩個人的時間,但是如果此時func1這時切換到讓func2執行,就可以不讓fun2等待func1需要等待的時間,就可以某種程度上實現併發(有點牽強,但是確實有一種func1 func2交替執行,你一句我一句這種併發的效果)

import

gevent

deffunc1():

print("

吃飯去嗎")

gevent.sleep(2) #

gevent可以在gevevt.sleep()自己認識的io操作切換

print("

那我們走吧")

gevent.sleep(2)

deffunc2():

print("吃"

) gevent.sleep(2)

print("好的"

)g1=gevent.spawn(func1)

g2=gevent.spawn(func2)

#g1.join() # 主線程等待結束

#g2.join()

gevent.joinall([g1,g2]) #

相當於上面的g1.join() g2.join()

gevent 就是當遇到gevent.sleep() io 時會自動切換;gevent()對普通的io (比如time模組的sleep,socket 以及urllib request等網路請求)是無法切換的:

import

gevent

import

time

deffunc1():

print("

func1:吃飯去嗎")

time.sleep(2) #

gevent對普通模組的io比如time.sleep()是無法完成切換的

print("

func1:那我們走吧")

time.sleep(1)

deffunc2():

print("

func2:吃")

time.sleep(2)

print("

func2:好的")

g1=gevent.spawn(func1)

g2=gevent.spawn(func2)

gevent.joinall([g1,g2])

#等待所有函式執行完 因為主線程跟使用gevent 切換函式執行是完全非同步的

執行結果:

那如果想在使用gevent在單執行緒執行函式內遇到其他模組的io(time.sleep()  socket模組的accept recv 以及urllib requests的網路請求)之間切換 可以在所有io請求的模組上面加上一句: from gevent import monkey;monkey.patch_all() 即可實現gevent在單執行緒 執行函式內遇到其他模組的io 也可以完成切換:

from gevent import monkey;monkey.patch_all()  #

就可以使用gevent在單執行緒執行函式內遇到其他模組的io操作時也可以完成切換

#但是這句話必須加在其他模組的最上面(socket time等包含io的模組)

import

time

import

gevent

deffunc1():

print("

func1:吃飯去嗎")

time.sleep(2)

print("

func1:那我們走吧")

time.sleep(1)

deffunc2():

print("

func2:吃")

time.sleep(2)

print("

func2:好的")

g1=gevent.spawn(func1)

g2=gevent.spawn(func2)

gevent.joinall([g1,g2])

#等待所有函式執行完 因為主線程跟使用gevent 切換函式執行是完全非同步的

執行結果:

暑期訓練 day40

暑期訓練 day40 趙景樂昨天主要在看書上的知識,積極備戰啊。看的題只有5道sg演算法的題。還是對這類題的方法不清楚,不明白他的sg演算法為什麼要這樣寫。昨天的題目我出了兩道,一道簽到題沒考慮等號錯了一遍,然後a 題暴力出來的。因為a題資料只有50 50,也不是太大,所以暴力是可行的,然後這類題在...

每日演算法 day 40

那些你早出晚歸付出的刻苦努力,你不想訓練,當你覺的太累了但還是要咬牙堅持的時候,那就是在追逐夢想,不要在意終點有什麼,要享受路途的過程,或許你不能成就夢想,但一定會有更偉大的事情隨之而來。mamba out 2020.3.25 最後乙個資料點卡著時間ac了差了幾十毫秒 本來想吸一口氧氣的結果不吸氧氣...

Day 40 文字特徵抽取,中文特徵值化

其實就是對文字資料進行特徵值化,運用到sklearn的類是sklearn.feature extraction.text.countvectorizer注意是在text模組下的。countvectorizer 返回的是詞頻矩陣 1.實列化countvectorizer 2.呼叫fit transfo...