本文摘自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》频道 >>
人民邮电出版社
python入门书籍,非常畅销,超高好评,python官方公认好书。
转载请注明出处:木庄网络博客 » web前端三大主流框架之Python异步框架如何工作?