web前端三大主流框架之Python异步框架如何工作?


本文摘自php中文网,作者Tomorin,侵删。

这篇文章我们从 socket 编程的例子来看看 Python 异步框架是如何工作的,需要了解下简单的 socket 编程以及 Linux 提供的 I/O 复用机制。 Python 异步框架也是基于操作系统底层提供的 I/O 复用机制来实现的,比如 linux 下可以使用 select/poll/epoll 等。 我们先看个简单的 python socket server 例子,Python 代码使用 Python3,确保可以使用 selectors 模块。

一个实例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import socket

HOST = 'localhost'    # The remote host

PORT = 8888 # Arbitrary non-privileged port

with 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 测试下它:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

package main

import (

    "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 文档给的例子

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

import selectors

import socket

sel = 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 来运行它了

以上就是web前端三大主流框架之Python异步框架如何工作?的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Python映射类型的相关介绍

Python进制间的转换介绍

tensorflow安装以及对jupyter notebook配置详解

Python字符串的处理那些事

jupyter怎么用

Python 通配符删除文件

Python描述符的用法介绍(附示例)

Python如何求出输入数的阶乘

tuple and list 练习

Python3实现简单的银行账户登录系统实例

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...