Python异步IO之select
1. select模块的基本使用(以socket为例)
1 # -*- coding:utf-8 -*-
2 # Author:Wong Du
3
4 import select
5 import socket
6 import queue
7
8 HOST_PORT = ("0.0.0.0", 9000)
9 print("\033[31;1mServer Addr:{0}\033[0m".format(HOST_PORT))
10
11 server = socket.socket()
12 server.bind(HOST_PORT)
13 server.listen(10)
14
15 inputs = [server, ] # 监测服务端socket的活跃状态和新socket连接活跃状态列表
16 outputs = [] # 发送数据给客户端的socket连接列表
17 msg_queue = {} # 发送给客户端的信息数据字典
18
19 # 断开socket连接函数
20 def disconnect():
21 print("\033[41;1mClient [{0}] disconnected...\033[0m".format(r.getpeername()))
22 if r in outputs:
23 outputs.remove(r)
24 inputs.remove(r) # 移除select监测连接
25 del msg_queue[r] # 删除消息队列
26
27
28
29 if __name__ == '__main__':
30 while True:
31 print("Waiting for socket to active...")
32
33 # 如果在select监测的对象里没有活跃状态的socket,则卡在这里;
34 # 当有活跃的socket对象时,把socket对象赋给readable,writeable,excetional;
35 readable, writeable, exceptional = select.select(inputs, outputs, inputs)
36 print("active connect:", readable, writeable, exceptional)
37
38 for r in readable: # 循环readable里活跃的socket对象
39 if r is server: # 如果活跃的是server的socket对象,则代表有新客户端socket连接进来了
40 conn, client_addr = server.accept() # 接收client对象
41 print("\033[32;1mConnected client addr:{0}\033[0m".format(client_addr)) # 打印连接进来的对象身份
42 inputs.append(conn) # 加入到inputs列表让select监测处理
43 msg_queue[conn] = queue.Queue() # 接收到的客户端连接,不立即返回,暂存在队列里,以后发送
44 else: # 如果活跃的不是server的socket对象,则代表客户端socket有数据发过来了
45 try:
46 data = r.recv(1024).decode() # 接收客户端数据
47 if data:
48 # r.getpeername()获取客户端连接的身份信息
49 print("\033[33;1mReceived [{0}] from the {1}\033[0m".format(data, r.getpeername()))
50 if r not in outputs:
51 outputs.append(r) # 把客户端连接加到outputs列表里
52 msg_queue[r].put(data.upper().encode()) # 把想要返回给客户端的数据放到相应的客户端连接队列里
53 else:
54 disconnect() # 连接断开
55 except ConnectionResetError as e: # 抓取客户端断开错误
56 disconnect() # 连接断开
57
58 for w in writeable:
59 # print("\033[34;1mReading to send to client {0}\033[0m".format(w.getpeername()))
60 try:
61 data = msg_queue[w].get_nowait() # 获取队列中的数据
62 w.send(data) # 发送给客户端
63 print("\033[34;1mSend [{0}] to client {1}\033[0m".format(data, w.getpeername()))
64 except queue.Empty as e:
65 print("No data to send to the client [{0}]".format(w.getpeername()))
66
67 outputs.remove(w) # 移除列表中需要发送数据的连接
68
69 for e in exceptional:
70 print("\033[41;1mClient [{0}] handles exception\033[0m".format(e.getpeername())) #select处理异常连接
71 if e in outputs:
72 outputs.remove(e)
73
74 inputs.remove(e)
75 del msg_queue[e]
select_socket_server
1 # -*- coding:utf-8 -*-
2 # Author:Wong Du
3
4 import socket
5
6 HOST_PORT = ("localhost", 9000)
7 client = socket.socket()
8 client.connect(HOST_PORT)
9
10 while True:
11 cmd = input("%s#" % HOST)
12 if not cmd:
13 continue
14 client.send(cmd.encode())
15 data = client.recv(1024)
16 print(data.decode())
select_socket_client
1 # -*- coding:utf-8 -*-
2 # Author:Wong Du
3
4 import socket
5 import time
6
7 server_addr = ("localhost", 9000)
8 client_socket = [socket.socket() for i in range(100)]
9
10 msg_data = "如果我是dj,你会爱我吗?"
11 count = 0
12
13
14 for client in client_socket:
15 try:
16 client.connect(server_addr)
17 print("Success to connected...")
18 client.send(msg_data.encode())
19 data = client.recv(1024)
20 print(data.decode())
21 count += 1
22 except ConnectionResetError:
23 print(count)
24 time.sleep(10)
select_socket_client高并发测试
2. selector模块的基本使用(以socket为例)
1 # -*- coding:utf-8 -*-
2 # Author:Wong Du
3
4 import selectors
5 import socket, queue
6
7 sel = selectors.DefaultSelector() # 生成一个sel对象
8 send_msg = {} # 返回信息列表
9
10 # 接收客户端连接函数
11 def accept(sock, mask):
12 conn, client_addr = sock.accept()
13 print("\033[33;1mClient {0} is connected...\033[0m".format(client_addr))
14 # sock.setbloking(False)
15 # 将客户端socket对象和read方法注册到sel里面
16 sel.register(conn, selectors.EVENT_READ, read)
17 send_msg[conn] = queue.Queue()
18
19 # 接收客户端发来数据函数
20 def read(r, mask):
21 try:
22 data = r.recv(1024).decode()
23 if data:
24 print("Received [{0}] from the client {1}".format(data, r.getpeername()))
25 # conn.send(data.upper())
26 send_msg[r].put(data.upper().encode())
27 sel.modify(r, selectors.EVENT_WRITE, write)
28 else:
29 disconnect(r)
30 except ConnectionResetError:
31 disconnect(r)
32
33 # 发送数据给客户端函数
34 def write(w, mask):
35 # print("\033[34;1mReading to send to client {0}\033[0m".format(w.getpeername()))
36 try:
37 data = send_msg[w].get_nowait() # 获取队列中的数据
38 w.send(data) # 发送给客户端
39 print("\033[34;1mSend [{0}] to client {1}\033[0m".format(data.decode(), w.getpeername()))
40 except queue.Empty as e:
41 print("No data to send to the client [{0}]".format(w.getpeername()))
42
43 sel.modify(w, selectors.EVENT_READ, read)
44
45 # 断开socket连接函数
46 def disconnect(conn):
47 print("\033[41;1mClient {0} disconnected...\033[0m".format(conn.getpeername()))
48 sel.unregister(conn)
49 conn.close()
50
51 # 初始化服务端连接
52 HOST_PORT = ("localhost", 20000)
53 server = socket.socket()
54 server.bind(HOST_PORT)
55 server.listen(10)
56 print("\033[31;1mServer Address: {0}\033[0m".format(HOST_PORT))
57 # 将服务端socket对象和accept方法注册到sel里面
58 sel.register(server, selectors.EVENT_READ, accept)
59
60 while True:
61 # 开启事件监测(阻塞),类似select的select.select(inputs, outputs, inputs),当有活跃连接时,
62 # 返回一个元组,元组内有SelectorKey对象和events事件编号
63 # SelectorKey对象内包含fileobj嵌套字对象,fd柄, events事件编号,data回调函数内存空间指针
64 print("\033[32;1mWaiting to connections...\033[0m")
65 events = sel.select()
66 print("Active events: %s" % events)
67
68 for key, mask in events:
69 # 获取socket回调函数内存指针,即accept函数
70 callback = key.data
71 # 调用函数并把socket和events传进去
72 callback(key.fileobj, mask)
selector_socket_server
1 # -*- coding:utf-8 -*-
2 # Author:Wong Du
3
4 import socket
5 HOST = "localhost"
6 Port = 20000
7 client = socket.socket()
8 client.connect((HOST, Port))
9
10 while True:
11 cmd = input("%s#" % HOST)
12 if not cmd:
13 continue
14 client.send(cmd.encode())
15 data = client.recv(1024)
16 print(data.decode())
selector_socket_client
Python异步IO之select的更多相关文章
- Python异步IO --- 轻松管理10k+并发连接
前言 异步操作在计算机软硬件体系中是一个普遍概念,根源在于参与协作的各实体处理速度上有明显差异.软件开发中遇到的多数情况是CPU与IO的速度不匹配,所以异步IO存在于各种编程框架中,客户端比如浏览 ...
- python异步IO编程(一)
python异步IO编程(一) 基础概念 协程:python generator与coroutine 异步IO (async IO):一种由多种语言实现的与语言无关的范例(或模型). asyncio ...
- python异步IO编程(二)
python异步IO编程(二) 目录 开门见山 Async IO设计模式 事件循环 asyncio 中的其他顶层函数 开门见山 下面我们用两个简单的例子来让你对异步IO有所了解 import asyn ...
- python的协程和异步io【select|poll|epoll】
协程又叫做微线程,协程是一种用户态的轻量级的线程,操作系统根本就不知道协程的存在,完全由用户来控制,协程拥有自己的的寄存器的上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来后, ...
- Python - 异步IO\数据库\队列\缓存
协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,协程一定是在单线程运行的. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和 ...
- python -- 异步IO 协程
python 3.4 >>> import asyncio >>> from datetime import datetime >>> @asyn ...
- Python异步IO
在IO操作的过程中,当前线程被挂起,而其他需要CPU执行的代码就无法被当前线程执行了. 我们可以使用多线程或者多进程来并发执行代码,为多个用户服务. 但是,一旦线程数量过多,CPU的时间就花在线程切换 ...
- Python异步IO之协程(一):从yield from到async的使用
引言:协程(coroutine)是Python中一直较为难理解的知识,但其在多任务协作中体现的效率又极为的突出.众所周知,Python中执行多任务还可以通过多进程或一个进程中的多线程来执行,但两者之中 ...
- Python 异步IO、IO多路复用
事件驱动模型 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
随机推荐
- luogu P4243 [JSOI2009]等差数列 题解
前言: 这题真ex... 强烈谴责在题解里面放毒瘤题链接的屑出题人! 吐 ️ 解析: 这题分成两步走. 首先,既然题目中的修改操作是区间加等差数列,那么就容易想到在差分数组上进行操作. 然后就是相当恶 ...
- STM32定时器学习---基本定时器
STM32F1系列的产品,除了互联网产品外,工作8个,3种定时器,其中一种就是基本定时器.那么STM32单片机的基本定时器如何操作以及编程呢? 下面我们就来详细的了解一下 STM32F1系列的产品,除 ...
- 字符串与模式匹配算法(六):Needleman–Wunsch算法
一.Needleman-Wunsch 算法 尼德曼-翁施算法(英语:Needleman-Wunsch Algorithm)是基于生物信息学的知识来匹配蛋白序列或者DNA序列的算法.这是将动态算法应用于 ...
- SpringBoot:Spring容器的启动过程
一.简述 Spring的启动过程就是IoC容器的启动过程,本质上就是创建和初始化Bean的工厂(BeanFactory),BeanFactory是整个SpringIoC的核心,Spring使用Bean ...
- 转:汇编中EBP寄存器和ESP寄存器的区别
EBP和ESP都是汇编中关于指针的寄存器.但是定义不同: (1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶.(2 ...
- Python Numpy matplotlib Histograms 直方图
import numpy as np import matplotlib.pyplot as plt mu,sigma = 2,0.5 v = np.random.normal(mu,sigma,10 ...
- 让Visual Studio x64 支持 __asm内联汇编
目录 让Visual Studio x64 支持 __asm内联汇编 Intel Parallel Studio XE 2016安装 设置Interl C++ Compiler 使VS x64支持内联 ...
- p->next = q, p = q->next, q->next = p->next的区别
- Java第三天【变量、常量、数据类型】
学习Java第三天!加油!请帖友看看有和不足的地方,和在下说一下,谢谢! 变量 变量(variable): 1.变量的本质就是代表"可操作的存储空间",空间位置是确定的,蛋里面放置 ...
- 第九届网安竞赛writeup
web easysql[已解决] uname=a') union select 1,extractvalue(1, concat(0x7e, (select database()),0x7e))#&a ...