python全棧開發 * 線程隊列 線程池 協程 * 180731

來源:互聯網
上載者:User

標籤:eve   高度   targe   start   []   span   put   cal   send   

一.線程隊列

隊列:
1.Queue
先進先出
內建鎖 資料安全 
from queue import Queue   
from multiprocessing import Queue (IPC隊列)
2.LifoQueue後進先出
後進先出
內建鎖 資料安全

from queue import LifoQueue    lq=LifoQueue(5)    lq.put(123)    lq.put(666)    lq.put(888)    lq.put(999)    lq.put("love")    print(lq.put_nowait("miss"))   #報錯 queue.Full    print(lq)    #  <queue.LifoQueue object at 0x0000017901BC8C88>    print(lq.get())   #love    print(lq.get())   #999    print(lq.get())   #888    print(lq.get())   #666    print(lq.get())   #123    #print(lq.get_nowait())     #報錯 queue.Empty
3.PriorityQueue優先順序隊列
(放元組,數字從小到大,英文字母按ASCII碼先後順序)
from queue import PriorityQueue    pq=PriorityQueue(4)    pq.put((10,"aaa"))    pq.put((5,"S"))    pq.put((5,"ccc"))    pq.put((10,"zzz"))    #pq.put_nowait((10,"bbb"))      #報錯queue.Full    print(pq)       #  <queue.PriorityQueue object at 0x000001D6FEF38C50> print(pq.get())    print(pq.get())   #(5, ‘ccc‘)    print(pq.get())   #(10, ‘aaa‘)    print(pq.get())   #(10, ‘zzz‘)    print(pq.get())   #(20, ‘bbb‘)    # print(pq.get_nowait())     # 報錯queue.Empty
二 線程池
Multiprocessing模組 內建進程池Pool
Threading 模組 沒有Pool(沒有線程池)
concurrent.futures協助你管理線程池和進程池
高度封裝
進程池/線程池的統一的統一的使用方法
import time    from threading import currentThread    from concurrent.futures import ProcessPoolExecutor    from concurrent.futures import ThreadPoolExecutor    def func(i):        time.sleep(1)        print("in %s %s"%(i,currentThread()))        return i**2    def back(fn):        print(fn.result(),currentThread())    t=ThreadPoolExecutor(5)    ret_l=[]    for i in range(20):        ret=t.submit(func,i).add_done_callback(back)        # ret_l.append(ret)    t.shutdown(wait=True)    #括弧裡可以省略    # for ret in ret_l:    #     print(ret.result())    print(666)
 ThreadPoolExecutor的相關方法:
1.t.map方法 啟動多線程任務 # t.map(func,range(20)) 替代for submit
2.t.submit(func,*args,**kwargs) 非同步提交任務
3.t.shutdown (wait=True) 相當於進程池的pool.close()+pool.join()操作 同步控制
wait=True,等待池內所有任務執行完畢回收完資源後才繼續
wait=False,立即返回,並不會等待池內的任務執行完畢
submit和map必須在shutdown之前
4.result擷取結果 ret.result()
5.回呼函數 add_done_callback(back)
在回呼函數內接收的參數是一個對象,需要通過result來擷取傳回值
在主進程中執行
三.協程
進程:資源分派的最小單位
線程 :CPU調度的最小單位
協程: 能在一條線程的基礎上,在多個任務之間互相切換
節省線程開啟的消耗
從python代碼的層級調度
正常的線程是CPU調度的最小單位
協程的調度並不是由作業系統來完成的.
(一).yield的機制就是協程
 def func():        print(1)        x=yield "aaa"        print(x)        yield "bbb"    g=func()    print(next(g))    print(g.send("***"))
(二).在多個函數之間互相切換的功能--協程
 def consumer():        while True:            x=yield            print(x)    def producer():        g=consumer()        next(g)        for i in range(10):            g.send(i)    producer()
yeild 只有程式之間的切換,沒有重利用任何IO操作的時間
greenlet(第三方模組) 程式環境切換
cmd : pip3 install 模組名 安裝第三方模組
(三).greenlet
協程模組 單純的程式切換耗費時間
 import time    from greenlet import greenlet    def eat():        print(‘吃‘)        time.sleep(1)        g2.switch()        print("吃完了")        time.sleep(1)        g2.switch()    def play():        print("玩")        time.sleep(1)        g1.switch()        print("玩美了")    g1=greenlet(eat)    g2=greenlet(play)    g1.switch()
(四).gevent
遇到IO就切換 使用協程減少IO操作帶來的時間消耗
greenlet 是gevent的底層
gevent是基於greenlet實現的
python代碼在控製程序的切換
第一版:
import time    import gevent    from gevent import monkey    def eat():        print("吃")        gevent.sleep(2)        print("吃完了")    def play():        print("玩")        gevent.sleep(2)        print("玩美了")    g1=gevent.spawn(eat)    g2=gevent.spawn(play)    g1.join()    #等待g1結束    g2.join()    #等待g2結束
第二版
要用gevent,需要將from gevent import monkey;monkey.patch_all()放到檔案的開頭
from gevent import monkey;monkey.patch_all()    import time    import gevent    def eat(name):        print("吃")        time.sleep(2)        print("%s吃完了"%name)    def play():        print("玩")        time.sleep(2)        print("玩美了")    g1=gevent.spawn(eat,"alex")   #括弧裡傳參第一個是函數名,後面可以跟多個參數可以是位置參數,也可以是關鍵字參數,都是傳給eat的    g2=gevent.spawn(play)    gevent.joinall([g1,g2])#  g1.join()和g2.join()合并成一個.    print(g1.value)         #None
四.協程起socket(tcp)
伺服器代碼
from gevent import monkey;monkey.patch_all()import socketimport geventdef talk(conn):    while True:        conn.send(b‘hallo‘)        print(conn.recv(1024))sk=socket.socket()sk.bind(("127.0.0.1",9902))sk.listen()while True:    conn,addr=sk.accept()    gevent.spawn(talk,conn)
用戶端代碼
import socketfrom threading import Threaddef client():    sk=socket.socket()    sk.connect(("127.0.0.1",9902))    while True:        print(sk.recv(1024))        sk.send(b‘hi‘)for i in range(5):    Thread(target=client).start()

 




 

python全棧開發 * 線程隊列 線程池 協程 * 180731

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.