epoll技术-多路复用进行抗并发
首先必须清楚,这个代码在windows下面无法执行,因为windows系统不支持,要搞就是在linux中撸
epoll技术核心的与socket的根本区别就是解决了轮询问题
epoll技术不是用的轮询,而是反向的,挨个去询问监控区里面的内容有没有变化太低端了,牛皮的都是吼一声,监控区里面的谁状态改变了自己报上名来
内核就干的这个事情,如果监控区里面的对象发生了状态的变化则会自动向系统发出一个信号,系统接收到信号后将这些状态变化的对象以列表的形式进行返回
之后的代码就跟上一篇说的逻辑一样
from socket import *
import select
def main():
# 创建对象
server = socket(AF_INET, SOCK_STREAM)
# 配置断开释放端口
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 挂起服务器
server.bind(('', 8888))
# 设置成监听模式
server.listen()
# 创建epoll对象
epoll = select.epoll()
# 使用epoll对象进行注册,注册的目的就是让内核对注册的内容进行监听
epoll.register(server.fileno(),select.EPOLLIN) # 其存储的是文件标识符
# 创建字典用于存储客户端连接上server之后创建的对象
obj = {}
# 创建字典用于客户端连接上server之后存储客户端信息
client_info = {}
while True:
# 内核进行阻塞监听,并将发生变动的文件标识符返回出来
epoll_list = epoll.poll()
# 遍历发生变动文件标识符
for fb, events in epoll_list: # 这个地方很坑,events虽然没有什么乱用,但是还是要写,因为epoll_list返回的是一个元组两个元素
# 进行判断,如果是用户的连接动作,则变动的文件标识符一定是sever
if fb == server.fileno():
# 表示用户连接,需要创建新的对象进行
new_server, link_client = server.accept()
print(f'用户{link_client}已经连接成功')
# 将新连接的对象注册到epoll中
epoll.register(new_server.fileno(), select.EPOLLIN)
# 将对象放入到对应的准备好的字典中
obj[new_server.fileno()] = new_server
# 将用户信息放到对应的字典中
client_info[new_server.fileno()] = link_client
else:
# 如果不是连接请求,则一定是已经连接的用户发送数据请求,这里就接收数据
# 读取数据
data = obj[fb].recv(1024)
print(f'收到来自用户{client_info[fb]}的数据:{data}')
# 收据接收完成周进行关闭连接
obj[fb].close()
# 需要将字典中的数据清除
del obj[fb]
del client_info[fb]
# 清除epoll中的注册信息
epoll.unregister(fb)
if __name__ == '__main__':
main()
需要注意的是:
epoll技术不仅对连接数没有限制,而且还采用了自发的监控模式,这就非常好的提升了整体抗并发的性能
话虽然如此,但是在并发这种问题上,肯定是要要求快速处理的,那么实际上python本身就不是一个以速度为有优势的语言,要想搞速度显然是使用c,所以对于解决并发问题,python几乎是没有用到