广告
返回顶部
首页 > 资讯 > 后端开发 > Python >深入理解python中的select模块
  • 389
分享到

深入理解python中的select模块

模块pythonselect 2022-06-04 18:06:51 389人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

简介 python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在linux中可用,windows仅支持select),另外也提供了kq

简介

python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统)

select方法

进程指定内核监听哪些文件描述符(最多监听1024个fd)的哪些事件,当没有文件描述符事件发生时,进程被阻塞;当一个或者多个文件描述符事件发生时,进程被唤醒。

当我们调用select()时:

  1、上下文切换转换为内核态

  2、将fd从用户空间复制到内核空间

  3、内核遍历所有fd,查看其对应事件是否发生

  4、如果没发生,将进程阻塞,当设备驱动产生中断或者timeout时间后,将进程唤醒,再次进行遍历

  5、返回遍历后的fd

  6、将fd从内核空间复制到用户空间

fd:file descriptor 文件描述符


fd_r_list, fd_w_list, fd_e_list = select.select(rlist, wlist, xlist, [timeout])

参数: 可接受四个参数(前三个必须)

rlist: wait until ready for reading wlist: wait until ready for writing xlist: wait for an “exceptional condition” timeout: 超时时间

返回值:三个列表

select方法用来监视文件描述符(当文件描述符条件不满足时,select会阻塞),当某个文件描述符状态改变后,会返回三个列表

1、当参数1 序列中的fd满足“可读”条件时,则获取发生变化的fd并添加到fd_r_list中

2、当参数2 序列中含有fd时,则将该序列中所有的fd添加到 fd_w_list中

3、当参数3 序列中的fd发生错误时,则将该发生错误的fd添加到 fd_e_list中

4、当超时时间为空,则select会一直阻塞,直到监听的句柄发生变化

当超时时间 = n(正整数)时,那么如果监听的句柄均无任何变化,则select会阻塞n秒,之后返回三个空列表,如果监听的句柄有变化,则直接执行。

实例:利用select实现一个可并发的服务端


import Socket
import select

s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
r_list = [s,]
num = 0
while True:
 rl, wl, error = select.select(r_list,[],[],10)
 num+=1
 print('counts is %s'%num)
 print("rl's length is %s"%len(rl))
 for fd in rl:
  if fd == s:
   conn, addr = fd.accept()
   r_list.append(conn)
   msg = conn.recv(200)
   conn.sendall(('first----%s'%conn.fileno()).encode())
  else:
   try:
    msg = fd.recv(200)
    fd.sendall('second'.encode())
   except ConnectionAbortedError:
    r_list.remove(fd)


s.close()

import socket

flag = 1
s = socket.socket()
s.connect(('127.0.0.1',8888))
while flag:
 input_msg = input('input>>>')
 if input_msg == '0':
  break
 s.sendall(input_msg.encode())
 msg = s.recv(1024)
 print(msg.decode())

s.close()

在服务端我们可以看到,我们需要不停的调用select, 这就意味着:

  1 当文件描述符过多时,文件描述符在用户空间与内核空间进行copy会很费时

  2 当文件描述符过多时,内核对文件描述符的遍历也很浪费时间

  3 select最大仅仅支持1024个文件描述符

poll与select相差不大,本文不作介绍

epoll方法:

epoll很好的改进了select:

  1、epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时,会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。

  2、epoll会在epoll_ctl时把指定的fd遍历一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd

  3、epoll对文件描述符没有额外限制


select.epoll(sizehint=-1, flags=0) 创建epoll对象


epoll.close()
Close the control file descriptor of the epoll object.关闭epoll对象的文件描述符

epoll.closed
True if the epoll object is closed.检测epoll对象是否关闭

epoll.fileno()
Return the file descriptor number of the control fd.返回epoll对象的文件描述符

epoll.fromfd(fd)
Create an epoll object from a given file descriptor.根据指定的fd创建epoll对象

epoll.reGISter(fd[, eventmask])
Register a fd descriptor with the epoll object.向epoll对象中注册fd和对应的事件

epoll.modify(fd, eventmask)
Modify a registered file descriptor.修改fd的事件

epoll.unregister(fd)
Remove a registered file descriptor from the epoll object.取消注册

epoll.poll(timeout=-1, maxevents=-1)
Wait for events. timeout in seconds (float)阻塞,直到注册的fd事件发生,会返回一个dict,格式为:{(fd1,event1),(fd2,event2),……(fdn,eventn)}

事件:


EPOLLIN Available for read 可读 状态符为1
EPOLLOUT Available for write 可写 状态符为4
EPOLLPRI Urgent data for read
EPOLLERR Error condition happened on the assoc. fd 发生错误 状态符为8
EPOLLHUP Hang up happened on the assoc. fd 挂起状态
EPOLLET Set Edge Trigger behavior, the default is Level Trigger behavior 默认为水平触发,设置该事件后则边缘触发
EPOLLONESHOT Set one-shot behavior. After one event is pulled out, the fd is internally disabled
EPOLLRDNORM Equivalent to EPOLLIN
EPOLLRDBAND Priority data band can be read.
EPOLLWRNORM Equivalent to EPOLLOUT
EPOLLWRBAND Priority data may be written.
EPOLLMSG Ignored.

水平触发和边缘触发:

Level_triggered(水平触发,有时也称条件触发):当被监控的文件描述符上有可读写事件发生时,epoll.poll()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll.poll()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率!!! 优点很明显:稳定可靠

Edge_triggered(边缘触发,有时也称状态触发):当被监控的文件描述符上有可读写事件发生时,epoll.poll()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll.poll()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!!缺点:某些条件下不可靠

epoll实例:


import socket
import select

s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
epoll_obj = select.epoll()
epoll_obj.register(s,select.EPOLLIN)
connections = {}
while True:
 events = epoll_obj.poll()
 for fd, event in events:
  print(fd,event)
  if fd == s.fileno():
   conn, addr = s.accept()
   connections[conn.fileno()] = conn
   epoll_obj.register(conn,select.EPOLLIN)
   msg = conn.recv(200)
   conn.sendall('ok'.encode())
  else:
   try:
    fd_obj = connections[fd]
    msg = fd_obj.recv(200)
    fd_obj.sendall('ok'.encode())
   except BrokenPipeError:
    epoll_obj.unregister(fd)
    connections[fd].close()
    del connections[fd]

s.close()
epoll_obj.close()

import socket

flag = 1
s = socket.socket()
s.connect(('127.0.0.1',8888))
while flag:
 input_msg = input('input>>>')
 if input_msg == '0':
  break
 s.sendall(input_msg.encode())
 msg = s.recv(1024)
 print(msg.decode())

s.close()

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对编程网的支持。

--结束END--

本文标题: 深入理解python中的select模块

本文链接: https://www.lsjlt.com/news/13370.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 深入理解python中的select模块
    简介 Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kq...
    99+
    2022-06-04
    模块 python select
  • 深入理解python中的atexit模块
    atexit 模块介绍 python atexit 模块定义了一个 register 函数,用于在 python 解释器中注册一个退出函数,这个函数在解释器正常终止时自动执行,一般用来做一些资源清理的操作...
    99+
    2022-06-04
    模块 python atexit
  • 深入解析Python中的urllib2模块
    Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库。这里总结了一些 urllib2 的使用细节。 Prox...
    99+
    2022-06-04
    模块 Python
  • python中jieba模块的深入了解
    目录一、前言        二、模块的安装三、jieba模块具体讲解3.1分词模式3.2cut()、lcut()3.2.1cut(s...
    99+
    2022-11-11
  • 深入理解Node中的buffer模块
    在Node、ES2015出现之前,前端工程师只需要进行一些简单的字符串或DOM操作就可以满足业务需要,所以对二进制数据是比较陌生。node出现以后,前端面对的技术场景发生了变化,可以深入到网络传输、文件操作...
    99+
    2022-06-04
    模块 Node buffer
  • 深入理解Python3中的http.client模块
    http 模块简介 Python3 中的 http 包中含有几个用来开发 HTTP 协议的模块。 http.client 是一个底层的 HTTP 协议客户端,被更高层的 urllib.request ...
    99+
    2022-06-04
    模块 http client
  • 深入理解Node.js的HTTP模块
    前言 我们知道传统的HTPP服务器会由Aphche、Nginx、IIS之类的软件来担任,但是nodejs并不需要,nodejs提供了http模块,自身就可以用来构建服务器,而且http模块是由C++实现的,...
    99+
    2022-06-04
    模块 Node js
  • 深入理解Nodejs Global 模块
    浏览器上有自己的全局对象 window,同理, nodejs 下也有自己的全局对象 global,并且在各个模块下 都可以直接访问 global 对象。 在 nodejs 中,除了可以直接使用 V8 Ja...
    99+
    2022-06-04
    模块 Nodejs Global
  • 深入理解node.js之path模块
    node之path模块 //引用该模块 var path = require("path"); 1、路径解析,得到规范化的路径格式 //对window系统,目录分隔为'', 对于UNIX系统,分隔...
    99+
    2022-06-04
    模块 node js
  • 深入了解Python的类与模块化
    目录学习目标1. 面向对象编程:类1.1 面向对象编程的基本概念1.2 自定义类1.3 再谈继承2. 模块2.1 导入模块2.2 导入Python标准模块2.3 单独导入模块中所需对...
    99+
    2022-11-12
  • 深入解析Python编程中JSON模块的使用
    JSON编码支持的基本数据类型为 None , bool , int , float 和 str , 以及包含这些类型数据的lists,tuples和dictionaries。 对于dictionaries...
    99+
    2022-06-04
    模块 Python JSON
  • python爬虫之request模块深入讲解
    目录一、概述二、安装和基本步骤使用三、http知识复习四、request请求模块的方法使用五,params和payload参数使用说明总结一、概述 在后期渗透测试中,经常会遇到需要向...
    99+
    2022-11-13
  • 深入理解Commonjs规范及Node模块实现
    前面的话 Node在实现中并非完全按照CommonJS规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性。本文将详细介绍NodeJS的模块实现 引入 nodejs是区别于javasc...
    99+
    2022-06-04
    模块 Commonjs Node
  • Python关于时间序列calendar模块的深入讲解
    大家好,在之前的文章中详细介绍了time和datetime模块的使用。这两个模块更多的是用于处理时间和日期相关的问题。 本文介绍的是第三个模块calendar,则主要是用于解决日历方...
    99+
    2022-11-12
  • 深入理解Python中的__builti
    0.说明        这里的说明主要是以Python 2.7为例,因为在Python 3+中,__builtin__模块被命名为builtins,下面主要是探讨Python 2.x中__builtin__模块和__builtins__模块...
    99+
    2023-01-31
    Python __builti
  • 深入理解python中的ThreadLocal
    ThreadLocal在threading模块中,可以见得它是为我们的线程服务的。 它的主要作用是存储当前线程的变量,各个线程之间的变量名是可以相同的,但是线程之间的变量是隔离的,也...
    99+
    2023-03-08
    python ThreadLocal
  • 深入聊聊Node中的File模块
    在聊 Stream/Buffer 的时候,我们已经开始使用require("fs")引入文件模块做一些操作了文件模块是对底层文件操作的封装,例如文件读写/打开关闭/删除添加等等文件模块最大的特点就是所有的方法都提供的同步...
    99+
    2023-05-14
    Node.js 前端
  • python中模块导入模式详解
    目录模块导入1.1 import导入模块1.2 from 模块名 import 导入模板的方法1.3 as 关键字OS模块操作文件OS模块的作用模块的制作、发布、安装3.1 模块制作...
    99+
    2022-11-11
  • 深入浅出Golang中select的实现原理
    目录概述select实现原理执行流程case数据结构执行select循环总结概述 在go语言中,select语句就是用来监听和channel有关的IO操作,当IO操作发生时,触发相应...
    99+
    2022-11-11
  • Node.js 源码阅读深入理解cjs模块系统
    目录前言源码阅读内置模块用户模块总结前言 相信大家都知道如何在 Node.js 中加载一个模块: const fs = require('fs'); const express = ...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作