亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

123 Python程序中的線程操作-協程

系統 1551 0

目錄

  • 一、什么是協程
  • 二、為什么要有協程
  • 三、協程的優缺點
  • 四、如何實現協程
  • 五、Gevent模塊
    • 5.1 模塊的安裝
    • 5.2 用法介紹
    • 5.3 代碼實例
  • 六、gevent之應用

一、什么是協程

協程: 就是 單線程 實現并發

協程概念本質是程序員抽象出來的,是人為的控制通過程序的IO去進行切換任務的執行

并發:任務切換+保存狀態

二、為什么要有協程

自己控制切換要比操作系統切換快的多.降低了單個線程的io堵塞時間,也就是實現了單線程下效率最高.

三、協程的優缺點

  • 優點:

    自己控制切換要比操作系統切換快的多

  • 缺點:

    1. 需要自己要檢測所有的io,但凡有一個阻塞整體都跟著阻塞.
    2. 無法利用多核優勢.

四、如何實現協程

其實協程的本質就是在單線程下實現并發,也就是通過生成器 yield next 進行迭代生成器,實現切換任務和保存任務。

在Python中我們需要使用gevnet模塊來實現協程

五、Gevent模塊

Gevent 是一個第三方庫,可以輕松通過gevent實現并發同步或異步編程,在gevent中用到的主要模式是Greenlet,它是以C擴展模塊形式接入Python的輕量級協程。 Greenlet全部運行在主程序操作系統進程的內部,但它們被協作式地調度。

5.1 模塊的安裝

安裝: pip3 install gevent

5.2 用法介紹

g1=gevent.spawn(func,1,,2,3,x=4,y=5) :創建一個協程對象g1,spawn括號內第一個參數是函數名,如eat,后面可以有多個參數,可以是位置實參或關鍵字實參,都是傳給函數eat的

          
            g2=gevent.spawn(func2)
          
        

g1.join() :等待g1結束

g2.join() :等待g2結束

上述兩步合作一步: gevent.joinall([g1,g2])

g1.value :拿到func1的返回值

5.3 代碼實例

通過 from gevent import monkey;

monkey.patch_all() 去補丁,捕獲所以IO

from gevent import monkey;monkey.patch_all() 必須放到被打補丁者的前面,如time,socket模塊之前。

          
            import time
from gevent import monkey;monkey.patch_all()
'''打了一個補丁,它可以實現捕獲非gevent的所有io'''
import gevent

def eat():
    print('eat 1')
    time.sleep(2)
    # gevent.sleep(2)   # 可以這樣單獨捕捉阻塞,但是太麻煩,所以直接打補丁,捕捉運行期間的全部IO
    print('eat 2')
def play():
    print('play 1')
    # 瘋狂的計算呢沒有io
    time.sleep(3)
    # gevent.sleep(3)   # 可以這樣單獨捕捉阻塞,但是太麻煩,所以直接打補丁,捕捉運行期間的全部IO
    print('play 2')

'''
gevent實現協程的模塊,它可以捕獲單線程中的io并去切換任務
'''
if __name__ == '__main__':
    # 把本該串行的代碼通過協程完成單線程并行
    start = time.time()
    g1 = gevent.spawn(eat)      # 創建一個協程對象
    g2 = gevent.spawn(play)
    # g1.join() # 等待回收協程對象
    # g2.join()
    gevent.joinall([g1,g2])     # 把上面兩步并一步
    end = time.time()
    print(end-start)
          
        

六、gevent之應用

通過gevent實現單線程下的socket并發

注意: from gevent import monkey;monkey.patch_all()一定要放到導入socket模塊之前,否則gevent無法識別socket的阻塞。

服務器

          
            import socket
from gevent import monkey; monkey.patch_all()   # 打補丁
import gevent

'''
基于協程的socket通訊

協程:單線程下實現并發
'''

def connec_interface(conn,addr):
    while 1:
        try:
            data = conn.recv(1024)
            if not data:
                break
            print(f"來自{addr}的消息:",data.decode("utf8"))
            data = input(f"與{addr}聊天")
            conn.send(data.encode("utf8"))
        except:
            break


if __name__ == '__main__':
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(("127.0.0.1",8080))
    server.listen(5)

    while 1:
        print("等待連接。。。")
        conn,addr = server.accept()
        print("連接成功")
        gevent.spawn(connec_interface, conn, addr)  # 創建一個協程對象
          
        

客戶端

          
            import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",8080))

while 1:
    msg = input("請輸入內容")
    client.send(msg.encode("utf8"))
    data = client.recv(1024)
    if not data:
        break
    print(data.decode("utf8"))
          
        

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 99爱视频在线观看 | 精品国产免费观看一区 | 国内外成人在线视频 | 在线视频www| 九九99久久精品影视 | 色综合小说天天综合网 | www.黄色免费 | 成人午夜精品网站在线观看 | 久久久成人网 | 久久er热这里只有精品23 | 国产福利午夜自产拍视频在线 | 91视频你懂的 | 毛片在线不卡 | 欧美激情高清免费不卡 | 国产一区二区三区在线免费 | 亚洲最新在线视频 | 亚洲一区二区三区高清 | 九九夜夜 | 激情综合色综合啪啪开心 | 日本一级毛片大片免费 | 国产成人亚洲精品77 | 国产成人a在一区线观看高清 | 91热爆在线 | 国产精品久久久一区二区三区 | 精品成人在线视频 | 一本一本久久a久久精品综合 | xxx色视频| 久久综合五月天 | 成人综合婷婷国产精品久久免费 | 国产精品乱码一区二区三区 | 欧美日韩国产在线成人网 | 欧美日韩麻豆 | 亚洲精品中文字幕乱码一区二区 | 四虎影院久久 | 四虎www成人影院观看 | 国产成人久久一区二区三区 | 一色屋精品亚洲香蕉网站 | 九九视频在线观看视频6偷拍 | 国产伦精品一区二区三区四区 | 九九精| 日韩欧美一区二区三区久久 |