Python Select模型(程序流程)(转)
缘由
之前写socket的CS模型代码,都是利用最原始的多线程方式。服务端是主线程,接到客户端的连接请求就从线程池中获取一个线程去处理整个socket连接的所有操作,虽然在连接数较短的情况下没有什么影响,但是当连接数很大的情况下,线程的切换和线程池的大小问题就明显起来了。
问题
应该存在一种方式可以让一个线程去处理多个连接,在连接有事情做的时候才过去处理,不然的话线程就挂起,让线程的利用率更高,于是后来学习了select以及epoll。在这里我重点总结一下select
select的原理
select是监听触发机制,监听可读和可写队列。当有事件发生时,进行遍历轮询事件发生的对象然后返回
比如在服务端启动之后把服务端添加到select的可读监听队列中,当有客户端请求连接服务端时,select函数会返回一个可读事件再让服务端接受客户端的连接。
select的返回方式可以是阻塞或者是非阻塞,非阻塞式的select处理方式是轮询的,会不断询问占用Cpu太多的资源和时间,所以建议使用阻塞等待返回的方式去使用select
优点:
没有了多线程的创建、销毁、切换带来的效率和内存上的消耗
缺点
select存在一个最大可监听文件描述符数量,所以会收到最大连接监听的限制
select在事件发生以后也是需要遍历监听对象,并不能直接定位到哪个对象,这个操作在对象数量庞大的情况下是个效率的瓶颈。所以后来有了epoll
程序流程描述:
1. 在创建了server的socket以后,通过无限循环监听select事件执行相应的操作
2. 客户端请求连接服务端,inputs非空,outputs为空,为queue增添客户端对象 ,readable非空,writeable为空
3. 服务端接收客户端发送的数据,为outputs增添消息数据,readable不为空,writeable为空,如果接收失败说明客户端断开了连接,则终止监听此客户端的消息,回到第1步等待客户端连接
4. outputs非空触发select事件,readable为空,writeable不为空,将queue中的数据发送到客户端,如果queue为空触发清除outputs操作
5. 等待客户端发送数据,回到第2步
服务端代码:
#!/usr/bin/env python
#*-* coding:utf-8 *-*
import select
import socket
import Queue
import time
import os
class Server():
#创建socket 套接字
def __init__(self):
self.server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.server.setblocking(False)
#配置参数
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_address= ('127.0.0.1',8008)
self.server.bind(self.server_address)
self.server.listen(10)
self.inputs = [self.server]
self.outputs = []
self.message_queues = {}
#timeout = 20
def run(self):
while self.inputs:
print "=================================="
print "waiting for next event"
print "inputs",self.inputs
print "outputs",self.outputs
print "queue", self.message_queues
#readable , writable , exceptional = select.select(inputs, outputs, inputs, timeout) 最后一个是超时,当前连接要是超过这个时间的话,就会kill
readable , writable , exceptional = select.select(self.inputs, self.outputs, self.inputs)
print "readable , writable , exceptional",readable , writable , exceptional
# When timeout reached , select return three empty lists
if not (readable or writable or exceptional) :
print "Time out ! "
break;
for s in readable :
if s is self.server:
#通过self.inputs查看是否有客户端来
connection, client_address = s.accept()
print " connection from ", client_address
connection.setblocking(0)
self.inputs.append(connection)
self.message_queues[connection] = Queue.Queue()
else:
try:
data = s.recv(1024)
except:
print " closing", client_address
if s in self.outputs :
self.outputs.remove(s)
self.inputs.remove(s)
s.close()
#清除队列信息
del self.message_queues[s]
else:
if data :
print " received " , data , "from ",s.getpeername()
self.message_queues[s].put(data)
# Add output channel for response
if s not in self.outputs:
self.outputs.append(s)
for s in writable:
try:
next_msg = self.message_queues[s].get_nowait()
except Queue.Empty:
print " " , s.getpeername() , 'queue empty'
self.outputs.remove(s)
else:
print " sending " , next_msg , " to ", s.getpeername()
os.popen('sleep 5').read()
s.send(next_msg)
for s in exceptional:
print " exception condition on ", s.getpeername()
#stop listening for input on the connection
self.inputs.remove(s)
if s in self.outputs:
self.outputs.remove(s)
s.close()
#清除队列信息
del self.message_queues[s]
if __name__ == "__main__":
s = Server()
s.run()
客户端代码:
# -*- coding:UTF-8 -*-
import socket
import os
import signal
import time, threading
def SendDataToServer(sock):
while True:
put = str(raw_input())
sock.send(put)
def ReceiveData(sock):
while True:
try:
data = sock.recv(1024)
time.sleep(1)
except:
print "Server Down!"
os._exit(0)
else:
if data:
print "RECEIVE:",data
if __name__ == "__main__":
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8008))
send_tick = threading.Thread(target=SendDataToServer, args=(s,))
rec_tick = threading.Thread(target=ReceiveData, args=(s,))
send_tick.start()
rec_tick.start()
Python Select模型(程序流程)(转)的更多相关文章
- Python Select模型
IO多路复用 IO多路复用就是我们经常说的select epoll.select和epoll的好处是单个process就可以同时处理多个网络IO.基本原理是select\epoll会不断的轮询所负责的 ...
- 基于select的python聊天室程序
python网络编程具体参考<python select网络编程详细介绍>. 在python中,select函数是一个对底层操作系统的直接访问的接口.它用来监控sockets.files和 ...
- 基于Select模型通信程序的编写,编译和执行
任务目标 编写Win32程序模拟实现基于Select模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递.客户端向服务器端发送"计算从1到100的奇数和",服务 ...
- 基于Select模型的Windows TCP服务端和客户端程序示例
最近跟着刘远东老师的<C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台)>,Bilibili视频地址为C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台),重新复习下 ...
- 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记.
说明 为何要写这篇文章 ,之前看过阿二的梦想船的<Poco::TCPServer框架解析> http://www.cppblog.com/richbirdandy/archive/2010 ...
- 【转】Select模型原理
Select模型原理利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,被迫 ...
- Select模型原理
Select模型原理 利用select函数,推断套接字上是否存在数据,或者是否能向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据, ...
- Windows I/O模型之一:Select模型
1.概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock) 四种调用模式: 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果 ...
- python select模块详解
要理解select.select模块其实主要就是要理解它的参数, 以及其三个返回值.select()方法接收并监控3个通信列表, 第一个是所有的输入的data,就是指外部发过来的数据,第2个是监控和接 ...
随机推荐
- Top 命令解析
TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中C ...
- 可访问范围 与 visual 或 abstract “修饰符”
protected:在当前类内定义,则在当前类“内部”可以调用,则在 派生子类"内部" 也可以调用 private,除去,在 派生子类"内部" 也可以调用,其它 ...
- 老老实实学WCF
老老实实学WCF 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我 ...
- patch-test-and-proc
实验环境 Ubuntu 14.04.5 LTS Linux - 4.15.6 为单个文件进程补丁操作 在桌面 Desktop 建立文件夹 patch ,作为实验用,然后进入patch 文件夹.建立测试 ...
- codeforces668b //Little Artem and Dance// Codeforces Round #348
题意:2种操作,转动或者奇偶位互换. 不论怎么交换,1的后两位一定是3,3的后两位一定是5.因此只要记录1,2的位置. //#pragma comment(linker,"/STACK:10 ...
- linux bash基本特性
一.bash 基础特性 (1)命令历史的功能 history: 环境变量 HISTSIZE:命令历史记录的条数 HISTFILE: ~/.bash_history 每个用户都有自己独立的命令历史文件 ...
- Dedecmsv5.7整合ueditor 图片上传添加水印
最近的项目是做dedecmsv5.7的二次开发,被要求上传的图片要加水印,百度ueditor编辑器不支持自动加水印,所以,找了很多资料整合记录一下,具体效果图 这里不仔细写dedecmsv5.7 整合 ...
- 文件名简体转繁体bat
@echo off rem 指定文件夹路径 set "fd=D:\下载的图片" rem 0为转换文件名,1为转换文件夹名,2为同时转换文件名和文件夹名 set f=0 rem 0为 ...
- 6月5 Smarty变量调节器
变量调节器:<{$a|变量调节器}> 主要修改此页面的信息来了解变量调节器:test0605/main.php和模板文件:main0605.html 1.利用给定的变量调节器 capita ...
- python-Tornado 框架
概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...