day19-IO多路复用
2024-09-29 20:25:04
1、I/O多路复用指:通过一种机制,可监听多个描述符(soket对象)(文件句柄),一旦某个描述符发送编号(一般指读就绪或写就绪),能够通知程序进行相应的读写操作。
2、I/O多路复用方式:select、poll 、epool。
win 只支持select
select:使用for循环,描述符最多1024个
pool:使用for循环实现,对文件描述符没有限制,
epoll:优化了实现方式,不在使用for循环,使用了异步的方式,效率高
2.1 select方式工作原理:
后面的1表示延时等待时间
nginx在内部就是基于epoll来实现的,使用epool+select来监听用户请求
2.2多路复用+socket实现伪并发处理示例
#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket
sk1 = socket.socket()
sk1.bind(('127.0.0.1', 8001))
sk1.listen() # sk2 = socket.socket()
# sk2.bind(('127.0.0.1', 8002))
# sk2.listen()
#
# sk3 = socket.socket()
# sk3.bind(('127.0.0.1', 8003))
# sk3.listen() # inputs = [sk1, sk2, sk3, ]
inputs = [sk1, ]
outputs = []
message_dict = {}
import select
while True:
#[sk1,sk2, ],内部自动监听sk1, sk2 两个对象, 一旦某个句柄发生变化,就能感知到
#如果有人连接 sk1
#r_list = [sk1, ]
#如果有人连接sk1发生编号
r_list, w_list, e_list = select.select(inputs, outputs, inputs, 1)
print("正在监听的socket对象总计:%d" % len(inputs))
print(r_list)
for sk1_or_conn in r_list:
#每一个连接对象
if sk1_or_conn == sk1:
conn, address = sk1_or_conn.accept()
inputs.append(conn)
message_dict[conn] = []
else:
#有老用户发消息了
try:
data_bytes = sk1_or_conn.recv(1024)
# data_str = str(data_bytes, encoding='utf-8')
# sk1_or_conn.sendall(bytes(data_str+'好', encoding='utf-8'))
except Exception as ex:
#用户终止连接
print(ex)
inputs.remove(sk1_or_conn)
else:
#用户正常发送消息
data_str = str(data_bytes, encoding='utf-8')
message_dict[sk1_or_conn].append(data_str)
# sk1_or_conn.sendall(bytes(data_str+'好', encoding='utf-8')) outputs.append(sk1_or_conn)
# conn.sendall(bytes('hello',encoding='utf-8'))
# conn.close() #w_list 仅仅保存了谁给我发过消息
for conn in w_list:
recv_str = message_dict[conn][0]
del message_dict[conn][0]
conn.sendall(bytes(recv_str+'好', encoding='utf-8'))
outputs.remove(conn) for sk1_or_conn in e_list:
inputs.remove(sk1_or_conn) # while True:
# conn, address = sk.accept()
# while True:
# content_bytes = conn.recv(1024)
# content_str = str(content_bytes, encoding='utf-8')
# conn.sendall(bytes(content_str + '好', encoding='utf-8'))
# conn.close()
server
#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket obj = socket.socket() obj.connect(('127.0.0.1',8001 )) while True:
inp = input('>>>>>')
obj.sendall(bytes(inp,encoding='utf-8'))
ret = str(obj.recv(1024),encoding='utf-8')
print(ret) #
# content = str(obj.recv(1024),encoding='utf-8')
# print(content)
obj.close()
# #阻塞
# print('等待中')
# ret_bytes = obj.recv(1024) #设置最高多接受的字节数,超过后需要等下次在接受
# print(str(ret_bytes,encoding='utf-8'))
# print('接受完成')
# # obj.close()
# while True:
# inp = input('请输入要发送的内容(q退出)\n >>>')
# if inp == 'q':
# obj.sendall(bytes(inp,encoding='utf-8'))
# break
# else:
# obj.sendall(bytes(inp,encoding='utf-8'))
# ret = str(obj.recv(1024),encoding='utf-8')
# print(ret)
# obj.close()
client
#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket
sk1 = socket.socket()
sk1.bind(('127.0.0.1', 8001))
sk1.listen() sk2 = socket.socket()
sk2.bind(('127.0.0.1', 8002))
sk2.listen() sk3 = socket.socket()
sk3.bind(('127.0.0.1', 8003))
sk3.listen() inputs = [sk1, sk2, sk3, ]
import select
while True:
#[sk1,sk2, ],内部自动监听sk1, sk2 两个对象, 一旦某个句柄发生变化,就能感知到
#如果有人连接 sk1
#r_list = [sk1]
r_list, w_list, e_list = select.select(inputs, [], [], 1)
for sk in r_list:
#每一个连接对象
conn, address = sk.accept()
conn.sendall(bytes('hello',encoding='utf-8'))
conn.close() # while True:
# conn, address = sk.accept()
# while True:
# content_bytes = conn.recv(1024)
# content_str = str(content_bytes, encoding='utf-8')
# conn.sendall(bytes(content_str + '好', encoding='utf-8'))
# conn.close()
server-demo2
2.3关于并发
3、初始超线程
#!/usr/bin/envpython
#-*-coding:utf-8-*-
importthreading
importtime defprocess(arg):
time.sleep(1)
print(arg) #foriinrange(10):
#process(i) foriinrange(10):
t=threading.Thread(target=process,args=(i,))
t.start()
demo
4、Soketserver原码解析
原理图
5、初始多线程
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time def process(arg):
time.sleep(1)
print(arg) # for i in range(10):
# process(i) for i in range(10):
t = threading.Thread(target=process, args=(i,))
t.start()
多线程
最新文章
- 用python2.7,采集新浪博客
- hibernate在使用sql查询query自动转化成model类型数据,query.addEntity
- 用jQuery调用微信api生成二维码
- Xcode免证书真机调试,解决cannot read entitlement data问题
- 如何解决vector 析构函数的异常 opencv Assert _CrtIsValidHeapPointer
- Reprint: Serialization
- Intervals
- Linux 查看系统硬件信息汇总 (部份实例详解Centoso为例)
- 剑指offer 12.代码的完整性 数值的整数次方
- Java基础第4天
- PAT 1011 A+B和C (15)(C++&JAVA&Python)
- CF1082解题报告
- iOS: 查看 UIView 的视图树
- vuex - 简单使用步骤梳理,轻松掌握、附源码
- python编码(七)
- python基础之迭代器协议和生成器
- Android -- service 服务的创建与使用,生命周期,电话监控器
- 10个android开发必备的开源项目
- Maven项目中突然找不到Build Path或maven dependencies library
- jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值