zoukankan      html  css  js  c++  java
  • python的select和epoll

    python的select和epoll

    1.select模型:

    • linux中每个套接字都是文件,都有唯一的文件描述符,这些设备的文件描述符被放在一个数组中,然后select调用的时候遍历这个数组,如果对于的文件描述符可读则会返回改文件描述符。当遍历结束之后,如果仍然没有一个可用设备文件描述符,select让用户进程则会睡眠,直到等待资源可用的时候在唤醒,遍历之前那个监视的数组。每次遍历都是以轮询的方式依次进行判断的。

    select实现回显服务器:

    
    from socket import *
    from select import *
    
    s = socket(2,1)
    s.setsockopt(1,2,1)
    s.bind(('',8080))
    s.listen(1024)
    
    s_list = [s.fileno(),]  #fileno()获取套接字的唯一描述符,每个套接字都是唯一不同的
    s_dict = {}
    
    while 1:
        list_readable,a,b = select(s_list,[],[]) #分别对应: 输入,输出,错误输出
        for i in list_readable:
            if i == s.fileno():
                conn,userinfo = s.accept()
                s_list.append(conn.fileno())
                s_dict[conn.fileno()] = conn
            else:
                cs = s_dict[i]
                recv_data = cs.recv(1024)
                if len(recv_data) <= 0:
                    s_dict[i].close()
                    s_dict.pop(i)
                    s_list.remove(i)
                else:
                    cs.send(recv_data)
    
    

    2.epoll模型:

    • select模型会受到文件描述符数量的限制,所以一般最多是1024个套接字,而epoll突破了此限制。
    • epoll采用的是事件通知机制,而不再是以轮询的方式挨个询问每个文件描述符的状态,节省cpu时间。
    • epoll是select的进阶版。一般情况下epoll效率更高

    epoll实现回显服务器:

    
    from socket import *
    from select import *
    
    s = socket(2,1)
    s.setsockopt(1,2,1)
    s.bind(('',8080))
    s.listen(1024)
    
    s_dict = {}
    
    epoll_instance = epoll()
    epoll_instance.register(s.fileno(),EPOLLIN|EPOLLET)
    while 1:
        epoll_list = epoll_instance.poll()
        for fd,event in epoll_list:
            if fd == s.fileno():
                cs,userinfo = s.accept()
                epoll_instance.register(cs.fileno(),EPOLLIN|EPOLLET)
                s_dict[cs.fileno()] = cs
            else:
                cs = s_dict[fd]
                recv_data = cs.recv(1024)
                print(recv_data.decode('gb2312'))
                if len(recv_data) > 0 :
                    cs.send(recv_data)
                else:
                    print('adsfasdf')
                    epoll_instance.unregister(fd)
                    cs.close()
                    s_dict.pop(fd)
                
    
    • 注:EPOLLIN(可读),EPOLLOUT(可写)
    • EPOLLET: 边缘触发模式(只通知一次)
    • EPOLLLT:水平触发模式(通知后没有做处理的话还会继续通知)

  • 相关阅读:
    Android Studio 开发
    Jsp编写的页面如何适应手机浏览器页面
    电影
    Oracle 拆分列为多行 Splitting string into multiple rows in Oracle
    sql server 2008 自动备份
    WINGIDE 激活失败
    python安装 错误 “User installations are disabled via policy on the machine”
    ble编程-外设发送数据到中心
    iOS开发-NSString去掉所有换行及空格
    ios9 字符串与UTF-8 互相转换
  • 原文地址:https://www.cnblogs.com/PrettyTom/p/6626229.html
Copyright © 2011-2022 走看看