服务端单进程实现并发
单进程实现并发的原理其实就是利用了系统的回收机制,如果内存中的数据没有任何变量进行指向的话,那么我们就叫这个数据ip的映射数为0,系统会自动的对映射数为0的数据ip进行清空
单进程中,服务端本来每次只能执行一个,但是如果使用变量进行接收到server创建的new_server则不会导致new_server被清空,还是可以继续执行
具体代码如下
from socket import *
def main():
# 创建对象
server = socket(AF_INET, SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 设置不阻塞
server.setblocking(False)
# 设置为挂起状态
server.bind(('', 8888))
# 设置为监听状态
server.listen()
# 创建一个列表用来暂时存储创建的对象
save_lists = []
while True:
# 接收数据
try:
new_server, client_info = server.accept()
# 创建之后的新套接字也需要进行取消其阻塞性
new_server.setblocking(False)
print(f'用户{client_info}已经连接')
# 如果已经有客户端连接则进行相关的操作
save_lists.append((new_server, client_info))
except:
pass
# 在列表中找出对应的对象进行数据获取
for sockets, link in save_lists: # 不管前面是否异常,都需要对列表中的数据进行遍历
try:
data = sockets.recv(1024)
except: # 出现异常表明客户端还没有发送数据过来
pass
else:
if data: # 如果是有数据的则表明有数据传输过来
# 打印对应的数据
print(f'来自用户{link}的数据{sockets}')
else: # 如果没有数据则表明对方要断开连接
sockets.close()
# 关闭之后将对应的的连接从列表中删除
save_lists.remove((sockets, link))
if __name__ == '__main__':
main()
save_list就是用来暂时存储的,list本身的每个索引都可以当做是一个变量,那么创建好对象之后扔进这个里面相当于就是变量赋值,这就是保证了对象有映射,遍历列表从而将对象提取出来
使用死循环进行一直执行,而且都设置了无阻塞的方式,其实这个程序就会执行的非常快,非常消耗cpu,不出错的话这个程序就把cpu占满.没有什么实际意义,就是联系一些
主要的思想在于使用中间变量进行暂时存储,之后再用遍历的方式进行针对每个对象依次进行取出执行,从而实现了单进程并发