python day10
IO多路复用
1. 监控多个描述符,内核发现进程一个或多个IO读取,就通知该进程
2. 减少系统开销:不必创建进程、线程、当然也不需要维护进程、线程
概述
select,poll,epoll
监听socket对象内部是否变化了?
什么时候变化?连接或收发消息
服务器端的socket对象发生变化 -》 有新连接来了...
sk: 有新连接来了...
conn:要收“发”消息了
IO多路复用 -- 监听socket对象内部是否变化了?
实现读写分离
import socket
import select
sk = socket.socket()
sk.bind(('127.0.0.1',9999))
sk.listen(5)
while True:
rlist,w,e, = select.select([sk,],[],[],1)
print(rlist)
for r in rlist:
print(r)
conn,address = r.accept()
conn.sendall(bytes('hello',encoding='utf-8'))
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9999,))
data = sk.recv(1024)
print(data)
while True:
input('>>>')
sk.close()
----------实现伪并发
---server.py
import socket
import select
sk = socket.socket()
sk.bind(('127.0.0.1', 9999,))
sk.listen(5)
inputs = [sk,]
while True:
rlist,w,e, = select.select(inputs, [],[],1)
print(len(inputs),len(rlist))
# 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为【sk】
# 监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,此时rlist的之为 【客户端】
# rlist = 【吴文煜,】
# rlist = 【张磊,白宇,】
# rlist = [sk,]
for r in rlist:
if r == sk:
# 新客户来连接
conn, address = r.accept()
# conn是什么?其实socket对象
inputs.append(conn)
conn.sendall(bytes('hello', encoding='utf-8'))
else:
# 有人给我发消息了
r.recv(1024)
# rlist = [sk,],rlist=[sk1,],rlist = [sk1,sk2]
# rlist = []
------client.py
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9999,))
data = sk.recv(1024)
print(data)
while True:
inp = input(">>>")
sk.sendall(bytes(inp,encoding='utf-8'))
sk.close()
结果
------客户端
b'hello'
------server端
1 0
1 1
2 0
2 0
2 0
2 0
2 1
3 0
3 0
实现读写分离
-------server.py
import socket
import select
sk = socket.socket()
sk.bind(('127.0.0.1', 9998,))
sk.listen(5)
inputs = [sk,]
outputs = []
while True:
rlist,wlist,e, = select.select(inputs, outputs,[],1)
print(len(inputs),len(rlist),len(wlist), len(outputs))
# 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为【sk】
# 监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,此时rlist的之为 【客户端】
# rlist = 【吴文煜,】
# rlist = 【张磊,白宇,】
# rlist = [sk,]
for r in rlist:
if r == sk:
# 新客户来连接
conn, address = r.accept()
# conn是什么?其实socket对象
inputs.append(conn)
conn.sendall(bytes('hello', encoding='utf-8'))
else:
# 有人给我发消息了
print('=======')
try:
ret = r.recv(1024)
# r.sendall(ret)
if not ret:
raise Exception('断开连接')
else:
outputs.append(r)
except Exception as e:
inputs.remove(r)
# 所有给我发过消息的人
for w in wlist:
w.sendall(bytes('response', encoding='utf-8'))
outputs.remove(w)
-------client.py
import socket
sk = socket.socket()
sk.connect(("127.0.0.1", 9998,))
data = sk.recv(1024)
print(data)
while True:
inp = input(">>>")
sk.sendall(bytes(inp,encoding='utf-8'))
print(sk.recv(1024))
sk.close()
结果
----client.py
b'hello'
>>>1
---sever.py
4 0 0 4
多线程:此程序包含两个线程
def f1(arg): #线程1
print(arg)
import threading
t = threading.Thread(target=f1,args=(123,)) #线程2
t.start()
f1(111)
多线程
import time
def f1(arg):
time.sleep(1)
print(arg)
# for i in range(10):
# f1(i)
# 单进程、单线程的应用程序
import threading
t = threading.Thread(target=f1,args=(123,))
t.setDaemon(True) #true,表示主线程不等待于此子线程
t.start() #不代表当前线程会被立即执行
t.join(2) #表示主线程到此,等待.....直到子线程执行完毕
#参数,表示主线程在此最多等待几秒
print('end')
print('end')
print('end')
print('end')
print('end')
print('end')
模块目录调用总结
import os
os.path.abspath(__file__) #我自己的绝对路径
os.path.dirname(os.path.abspath(__file__)) #所在目录
os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #脚本所在目录的上级目录