日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python并发编程6-协程

發布時間:2025/3/15 python 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python并发编程6-协程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、基礎

# 進程 啟動多個進程 進程之間是由操作系統(時間片輪轉)負責調用 # 線程 啟動多個線程 真正被CPU執行的最小單位是線程# 開啟一個線程 創建一個線程 寄存器 堆棧# 關閉一個線程 等都需要時間 # 協程:本質上是一個線程# 能夠在多個任務之間切換來節省一些IO時間# 協程切換也需要時間,但是遠遠小于線程進程開銷時間 # 實現并發的手段

2 協程應用背景

import time '''1''' def consumer(): # 生成器函數print(123)while True:x=yieldprint('**',x) c=consumer() # c為生成器,此時函數并沒有執行 next(c) c.send(1)

程序執行順序:

程序運行結果:

3 在一個程序上進行兩個任務的切換

'''2 在一個程序上進行兩個任務的切換''' def consumer(): # 生成器函數while True:x=yieldtime.sleep(1)print('處理了數據',x) def producer():c=consumer()next(c)for i in range(3):time.sleep(1)print('生產了數據:',i)c.send(i) producer()

程序執行順序:

程序運行結果:

4、協程切換:切換后接著執行-greenlet模塊

'''3 協程切換:切換后接著執行''' from greenlet import greenlet # 真正的協程模塊就是使用greenlet完成的切換 def eat():print('eating start')g2.switch()print('eating end')g2.switch() def play():print('playing start')g1.switch()print('playing end') g1=greenlet(eat) g2=greenlet(play) g1.switch()

程序執行順序:

程序執行結果:

5 協程切換 gevent

# spawn(func) 大量生產 # join() # .value 得到方法的返回值

?例子1:

import geventdef eat():print('eating start')gevent.sleep(1)print('eating end') def play():print('playing start')gevent.sleep(1)print('playing end') g1=gevent.spawn(eat) # 開啟一個協程 g2=gevent.spawn(play) g1.join() # 主線程等待g1結束 g2.join() # 主線程等待g2結束

?運行結果:

協程對time.sleep(1)不會有效果。只對gevent.sleep(1)有效果。除非用monkey模塊。如下:

from gevent import monkey;monkey.patch_all() # 有了這句代碼,自動會把IO操作打包。否則就需要用gevent.sleep() import gevent def eat():print('eat:', threading.current_thread().getName()) #DummyThread-1假線程print('eating start')time.sleep(1) # IO事件print('eating end') def play():print('play:', threading.current_thread().getName())print('playing start')time.sleep(1) # IO事件print('playing end') g1=gevent.spawn(eat) # 開啟一個協程 g2=gevent.spawn(play) g1.join() g2.join()

運行結果:

協程屬于偽線程

6 同步和異步

# 進程和線程的狀態切換是由操作系統完成 # 協程任務之間的切換是由程序(代碼)完成。# 只有遇到協程模塊能識別的IO操作的時候,程序才會進行任務切換,實現并發的效果#同步和異步:在高IO之間使用協程操作 # 協程 : 能夠在一個線程中實現并發效果的概念# 能夠規避一些任務中的IO操作# 在任務的執行過程中檢測到IO就切換到其他任務

?

from gevent import monkey;monkey.patch_all() # 必須寫在import其他模塊之前 import time import gevent def task():time.sleep(1)print(12345) def sync():for i in range(10):task() def async():g_lst=[]for i in range(10):g=gevent.spawn(task)g_lst.append(g)# for g in g_lst:g.join()gevent.joinall(g_lst) sync() async()

運行結果:

輸出過程:先一秒一秒輸出12345.輸出四個后。同時輸出5個12345

7 利用協程實現socket聊天

server模塊:

import socket from gevent import monkey;monkey.patch_all() import gevent def talk(conn):conn.send(b'hello')print(conn.recv(1024).decode('utf-8'))conn.close() sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() while True:conn,addr=sk.accept()gevent.spawn(talk,conn) sk.close()

client模塊:
?

import socket sk=socket.socket() sk.connect(('127.0.0.1',8080)) print(sk.recv(1024)) msg=input('>>>').encode('utf-8') sk.send(msg) sk.close()

運行結果:

進程,線程,協程個數關系

總結

以上是生活随笔為你收集整理的python并发编程6-协程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。