最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)異步IO的示例

 更新時間:2020年11月05日 14:59:35   作者:-零  
這篇文章主要介紹了Python實(shí)現(xiàn)異步IO的示例,幫助大家更好的理解和使用python,感興趣的朋友可以了解下

前言

  用阻塞 API 寫同步代碼最簡單,但一個線程同一時間只能處理一個請求,有限的線程數(shù)導(dǎo)致無法實(shí)現(xiàn)萬級別的并發(fā)連接,過多的線程切換也搶走了 CPU 的時間,從而降低了每秒能夠處理的請求數(shù)量。為了達(dá)到高并發(fā),你可能會選擇一個異步框架,用非阻塞 API 把業(yè)務(wù)邏輯打亂到多個回調(diào)函數(shù),通過多路復(fù)用與事件循環(huán)的方式實(shí)現(xiàn)高并發(fā)。

磁盤 IO 為例,描述了多線程中使用阻塞方法讀磁盤,2 個線程間的切換方式。那么,怎么才能實(shí)現(xiàn)高并發(fā)呢?

把上圖中本來由內(nèi)核實(shí)現(xiàn)的請求切換工作,交由用戶態(tài)的代碼來完成就可以了,異步化編程通過應(yīng)用層代碼實(shí)現(xiàn)了請求切換,降低了切換成本和內(nèi)存占用空間。異步化依賴于 IO 多路復(fù)用機(jī)制,比如 Linux 的 epoll 或者 Windows 上的 iocp,同時,必須把阻塞方法更改為非阻塞方法,才能避免內(nèi)核切換帶來的巨大消耗。Nginx、Redis 等高性能服務(wù)都依賴異步化實(shí)現(xiàn)了百萬量級的并發(fā)。

下圖描述了異步 IO 的非阻塞讀和異步框架結(jié)合后,是如何切換請求的。

然而,寫異步化代碼很容易出錯。因?yàn)樗凶枞瘮?shù),都需要通過非阻塞的系統(tǒng)調(diào)用拆分成兩個函數(shù)。雖然這兩個函數(shù)共同完成一個功能,但調(diào)用方式卻不同。第一個函數(shù)由你顯式調(diào)用,第二個函數(shù)則由多路復(fù)用機(jī)制調(diào)用。

這種方式違反了軟件工程的內(nèi)聚性原則,函數(shù)間同步數(shù)據(jù)也更復(fù)雜。特別是條件分支眾多、涉及大量系統(tǒng)調(diào)用時,異步化的改造工作會非常困難。

Python如何實(shí)現(xiàn)異步調(diào)用

from flask import Flask
import time
app = Flask(__name__)


@app.route('/bar')
def bar():
  time.sleep(1)
  return '<h1>bar!</h1>'

@app.route('/foo')
def foo():
  time.sleep(1)
  return '<h1>foo!</h1>'
if __name__ == '__main__':
  app.run(host='127.0.0.1',port=5555,debug=True)

采用同步的方式調(diào)用

import requests
import time

starttime = time.time()
print(requests.get('http://127.0.0.1:5555/bar').content)
print(requests.get('http://127.0.0.1:5555/foo').content)
print("消耗時間: ",time.time() -starttime)

b'<h1>bar!</h1>'
b'<h1>foo!</h1>'
消耗時間:  2.015509605407715

采樣異步的方式調(diào)用:

重點(diǎn):

1.將阻塞io改為非阻塞io;

2.多路復(fù)用io監(jiān)聽內(nèi)核事件,事件觸發(fā)通過回調(diào)函數(shù);

3.用戶態(tài)代碼采取事件循環(huán)的方式獲取事件,執(zhí)行事件的回調(diào)函數(shù);

import selectors
import socket
import time
# from asynrequest import ParserHttp
class asynhttp:
  def __init__(self):
    self.selecter = selectors.DefaultSelector()

  def get(self,url,optiondict = None):
    global reqcount
    reqcount += 1
    s = socket.socket()
    s.setblocking(False)
    try:
      s.connect(('127.0.0.1',5555))
    except BlockingIOError:
      pass
    requset = 'GET %s HTTP/1.0\r\n\r\n' % url
    callback = lambda : self.send(s,requset)
    self.selecter.register(s.fileno(),selectors.EVENT_WRITE,callback)

  def send(self,s,requset):
    self.selecter.unregister(s.fileno())
    s.send(requset.encode())
    chunks = []
    callback = lambda: self.recv(s,chunks)
    self.selecter.register(s.fileno(),selectors.EVENT_READ,callback)

  def recv(self,s,chunks):
    self.selecter.unregister(s.fileno())
    chunk = s.recv(1024)
    if chunk:
      chunks.append(chunk)
      callback = lambda: self.recv(s,chunks)
      self.selecter.register(s.fileno(), selectors.EVENT_READ, callback)
    else:
      global reqcount
      reqcount -= 1
      request_first,request_headers,request_content,_ = ParserHttp.parser(b''.join(chunks))
      print("解析數(shù)據(jù):",request_first,request_headers,request_content)
      print((b''.join(chunks)).decode())
      return (b''.join(chunks)).decode()

starttime = time.time()
reqcount = 0
asynhttper = asynhttp()
asynhttper.get('/bar')
asynhttper.get('/foo')
while reqcount:
  events = asynhttper.selecter.select()
  for event,mask in events:
    func = event.data
    func()
print("消耗時間:" ,time.time() - starttime)

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 13
Server: Werkzeug/1.0.1 Python/3.7.7
Date: Thu, 15 Oct 2020 03:28:16 GMT

<h1>bar!</h1>
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 13
Server: Werkzeug/1.0.1 Python/3.7.7
Date: Thu, 15 Oct 2020 03:28:16 GMT

<h1>foo!</h1>
消耗時間: 1.0127637386322021

以上就是Python實(shí)現(xiàn)異步IO的示例的詳細(xì)內(nèi)容,更多關(guān)于python 異步IO的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python執(zhí)行時間的幾種計(jì)算方法

    Python執(zhí)行時間的幾種計(jì)算方法

    這篇文章主要介紹了Python執(zhí)行時間的幾種計(jì)算方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 詳解requirements.txt的生成和安裝

    詳解requirements.txt的生成和安裝

    本文主要介紹了詳解requirements.txt的生成和安裝,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python高階函數(shù)map()?簡介和使用詳解

    Python高階函數(shù)map()?簡介和使用詳解

    map()?函數(shù)是Python中的內(nèi)置函數(shù),這個函數(shù)又叫做映射函數(shù),其實(shí)里面具有一個迭代器的功能,會依次遍歷可迭代對象進(jìn)行相關(guān)的操作,這篇文章主要介紹了Python高階函數(shù)map()?簡介和使用詳解,需要的朋友可以參考下
    2023-03-03
  • 深入解析神經(jīng)網(wǎng)絡(luò)從原理到實(shí)現(xiàn)

    深入解析神經(jīng)網(wǎng)絡(luò)從原理到實(shí)現(xiàn)

    這篇文章主要介紹了深入解析神經(jīng)網(wǎng)絡(luò)從原理到實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Python利用pandas和matplotlib實(shí)現(xiàn)繪制圓環(huán)圖

    Python利用pandas和matplotlib實(shí)現(xiàn)繪制圓環(huán)圖

    在可視化的過程中,圓環(huán)圖是一種常用的方式,特別適合于展示各類別占比情況,本文將介紹如何使用 Python中的 pandas 和 matplotlib 庫,來制作一個店鋪銷量占比的圓環(huán)圖,需要的可以參考下
    2023-11-11
  • python 運(yùn)用Django 開發(fā)后臺接口的實(shí)例

    python 運(yùn)用Django 開發(fā)后臺接口的實(shí)例

    今天小編就為大家分享一篇python 運(yùn)用Django 開發(fā)后臺接口的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • 詳解numpy.meshgrid()方法使用

    詳解numpy.meshgrid()方法使用

    這篇文章主要介紹了詳解numpy.meshgrid()方法使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • python opencv實(shí)現(xiàn)簡易畫圖板

    python opencv實(shí)現(xiàn)簡易畫圖板

    這篇文章主要為大家詳細(xì)介紹了python opencv實(shí)現(xiàn)簡易畫圖板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 基于Python繪制一個摸魚倒計(jì)時界面

    基于Python繪制一個摸魚倒計(jì)時界面

    前端時間推出了一個摸魚APP,這篇文章將為大家介紹基于Python繪制一個摸魚倒計(jì)時界面,文中的示例代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下
    2021-12-12
  • python學(xué)習(xí)之panda數(shù)據(jù)分析核心支持庫

    python學(xué)習(xí)之panda數(shù)據(jù)分析核心支持庫

    這篇文章主要給大家介紹了關(guān)于python學(xué)習(xí)之panda數(shù)據(jù)分析核心支持庫的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評論

吉隆县| 祁阳县| 色达县| 昭通市| 洪泽县| 大名县| 金塔县| 通渭县| 玛多县| 嫩江县| 太仆寺旗| 新野县| 临沭县| 伊春市| 柳林县| 乳源| 岚皋县| 施秉县| 三穗县| 乐山市| 乐安县| 双辽市| 陇西县| 祁门县| 祁连县| 慈利县| 门源| 彝良县| 正定县| 河南省| 永靖县| 安泽县| 禹州市| 通江县| 淮南市| 桐梓县| 芮城县| 崇仁县| 桂阳县| 四川省| 任丘市|