day34-2 多路复用之epoll

news/2024/7/9 19:28:13 标签: epoll

epoll">epoll

select存在的问题

    1. select,需要遍历socket列表,频繁的对等待队列进行添加移除操作
    1. 数据到达后还需要遍历所有的socket才能获知哪些socket有数据

两个操作消耗的时间随着要监控的socket的数量增加而大大增加,所以最大只能监视1024个socket。

于是就推出了epollepoll对问题一方案是把等待队列的维护与阻塞进程这两个操作分开了

对问题2是自己维护了一个等待队列,避免了遍历所有的socket。需要注意:epoll仅能在linux中使用

epoll相关函数">epoll相关函数

import select  # 导入select模块
epoll = select.epoll()  # 创建一个epoll对象

epoll.register(文件句柄,事件类型)  # 注册要监视的文件句柄和事件
# 事件类型:
    select.EPOLLIN  # 可读事件
    select.EPOLLOUT  # 可写事件
    select.EPOLLERR  # 错误事件
    select.EPOLLHUP  # 客户端断开事件
    
epoll.unregister(文件句柄)  # 销毁文件句柄

epoll.poll(timeout)  # 当文件句柄发生变化,则会以列表的形式主动报告给用户进程,timeout为超时时间,默认为-1,即一直等待直到文件句柄发生变化,如果指定为1,那么epoll每1秒汇报一次当前文件句柄的变化情况,如果无变化则返回空

epoll.fileno()  # 返回epoll的控制文件描述符
epoll.modify(fineno, event)  # 修改文件描述符所对应的事件
epoll.fromfd(filena)  # 从1个指定的文件描述符创建1个epoll对象
epoll.close()  # 关闭epoll对象的控制文件描述符

案例

import select
from socket import *

server = socket()
server.bind(('127.0.0.1', 8000))
server.listen(5)

# 创建一个epoll对象
epoll = select.epoll()

# 注册读就绪事件(有数据可以读取了)
# s.fileno()用于获取文件描述符
epoll.register(server.fileno(), select.EPOLLIN)

# 存储文件描述符与socket的对应关系
fd_socket = {server.fileno(): server}

msgs = []

while True:
    # 会阻塞,直到你关注的事件发生
    for fd, event in epoll.poll():
        sock = fd_socket[fd]
        print(fd, event)
        # 返回的是文件描述符,需要获取对用socket
        if sock == server:
            client, addr = server.accept()
            # 注册客户端写就绪
            epoll.register(client.fileno(), select.EPOLLIN)
            # 添加对应关系
            fd_socket[client.fileno()] = client

        # 读就绪
        elif event == select.EPOLLIN:
            data = sock.recv(1024)
            if not data:
                # 注销事件
                epoll.unregister(fd)
                # 关闭socket
                socket.close()
                # 删除socket对应关系
                del fd_socket[fd]
                print("somebody ....")
                continue
            print(data.decode('utf8'))
            # 读完数据,需要把数据发回去。所以接下来更改为写就绪事件
            epoll.modify(fd, select.EPOLLOUT)
            # 记录数据
            msgs.append((sock, data.upper()))
        elif event == select.EPOLLOUT:
            for item in msgs[:]:
                if item[0] == sock:
                    sock.send(item[1])
                    msgs.remove(item)
            # 切换关注事件为写就绪
            epoll.modify(fd, select.EPOLLIN)

转载于:https://www.cnblogs.com/863652104kai/p/11166025.html


http://www.niftyadmin.cn/n/1359028.html

相关文章

XXE漏洞学习

0X00:前言 介绍: XXE漏洞全称XML External Entity Injection 即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执…

20190710-汉诺塔算法

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱…

英文题面翻译01

英文题面:来源地址:A Simple Math Problem | JXNUOJ A Simple Math Problem 1000ms 131072K 描述: Huanhuan challenges you to a simple math problem. Define F(x) as the sum of the decimal digits of x. For example: F(123)1236,…

英文题面翻译02

英文原题:题目来源:Apple | JXNUOJ Apple 1000ms 262144K 描述: There are a box of apples,which contains N apples. Youre going to give them to M person. It is required that everyone must be given a positive integer apple, a…

echo 与 od -x 与 %!xxd 命令

echo 与 od -x 与 %!xxd 命令 echo 命令 -n 选项 可以使其不带换行符od -x 命令可以查看文件的16进制表示%!xxd 可以在vim编辑器中dump成16进制表示转载于:https://www.cnblogs.com/jeanschen/p/3183799.html

英文题面翻译03

英文原题:题目来源:Charging | JXNUOJ Charging 1000ms131072K 描述: Xxy is the king of the universe. In order to resist the invasion, he ordered the construction of many space warships.Now,he wants to charge his space ship…

在PC上使用苹果蓝牙无线键盘

Thinkpad X230是最近用的比较频繁的电脑,自带蓝牙;平日一直挂在底座上,拖着显示器、鼠标、键盘工作。苹果蓝牙无线键盘(Apple Wireless Keyboard)买了有好几年了,最近一直闲放着。闲来无事,试试…