web前端三大主流架構之Python非同步架構如何工作?

來源:互聯網
上載者:User
這篇文章我們從 socket 編程的例子來看看 Python 非同步架構是如何工作的,需要瞭解下簡單的 socket 編程以及 Linux 提供的 I/O 複用機制。 Python 非同步架構也是基於作業系統底層提供的 I/O 複用機制來實現的,比如 linux 下可以使用 select/poll/epoll 等。 我們先看個簡單的 python socket server 例子,Python 代碼使用 Python3,確保可以使用 selectors 模組。

一個執行個體

import socketHOST = 'localhost'    # The remote hostPORT = 8888 # Arbitrary non-privileged portwith socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)    s.bind((HOST, PORT))    s.listen(50)    while True:        conn, addr = s.accept()        print('Connected by', addr)        with conn:            while 1:                data = conn.recv(1024)                if not data:                    break                conn.sendall(data)

我們下邊用一個 golang 的 tcp client 測試下它:

package mainimport (    "fmt"    "net"    "os"    "sync")func sendMessage(msg string) error {    conn, err := net.Dial("tcp", "localhost:8888")    if err != nil {        return fmt.Errorf("error: %v", err)    }    defer conn.Close()    _, err = conn.Write([]byte("hello"))    if err != nil {        return fmt.Errorf("error: %v", err)    }    reply := make([]byte, 1024)    _, err = conn.Read(reply)    if err != nil {        println("Write to server failed:", err.Error())        os.Exit(1)    }    println("reply from server=", string(reply))    return nil}func main() {    var wg sync.WaitGroup    nbGoroutines := 20    wg.Add(nbGoroutines)    for k := 0; k < nbGoroutines; k++ {        go func() {            err := sendMessage("hello")            if err != nil {                fmt.Printf("fail: %v\n", err)            }            wg.Done()        }()    }    wg.Wait()}

使用 go 運行它可以看到輸出。

接下來我們使用 python3 提供的 selectros 來改造它,這個模組封裝了作業系統底層提供的 I/O 複用機制,比如 linux 上使用了 epoll。通過 I/O 複用機制我們可以監聽多個檔案描述符的可讀寫事件並且註冊回呼函數,擁有更好的並發效能。 先看 python3 的 selectors 文檔給的例子

import selectorsimport socketsel = selectors.DefaultSelector()def accept(sock, mask):    conn, addr = sock.accept()  # Should be ready    print('accepted', conn, 'from', addr)    conn.setblocking(False)    sel.register(conn, selectors.EVENT_READ, read)def read(conn, mask):    data = conn.recv(1000)  # Should be ready    if data:        print('echoing', repr(data), 'to', conn)        conn.send(data)  # Hope it won't block    else:        print('closing', conn)        sel.unregister(conn)        conn.close()sock = socket.socket()sock.bind(('localhost', 1234))sock.listen(100)sock.setblocking(False)sel.register(sock, selectors.EVENT_READ, accept)while True:  # 這其實就是通常在非同步架構中所說的 event loop 啦    events = sel.select()    for key, mask in events:        callback = key.data        callback(key.fileobj, mask)

我們來運行下這個 使用了 seelctors I/O 複用機制的 tcp echo server 看下輸出結果。

到這裡就差不多了,我們再繼續運行 go 寫的 tcp client 來測試它看結果。

在後邊教程中我們將使用 python 的 coroutine 而不是回呼函數來改造這個例子,這樣一來我們就能使用 async/await 來運行它了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.