• python并发(阻塞、非阻塞、epoll)


    在Linux系统中

    01 阻塞服务端

    特征:1对1,阻塞。
     1 import socket
     2 
     3 server = socket.socket()        #生成套接字对象
     4 server.bind(('0.0.0.0', 8000))    #套接字绑定ip和端口,变为监听套接字
     5 server.listen(5)                    #开始监听
     6 
     7 while True:
     8     conn, addr = server.accept()        #建立连接,生成对等套接字
     9     print('用户连接:', addr)
    10     while True:
    11         try:
    12             data = conn.recv(1024)
    13             if data == b'Q' or data == b'q':
    14                 print('用户退出:', addr)
    15                 break
    16             else:
    17                 print('收到的消息:', data.decode())
    18                 conn.send(data)
    19         except Exception as e:
    20             print(e)
    21             conn.close()
    22             break

    02 非阻塞服务端

    特征:1对多,轮询,非阻塞,占用资源多。
     1 import socket
     2 
     3 server = socket.socket()        #创建套接字
     4 server.setblocking(False)       #把套接字设置为非阻塞
     5 server.bind(('0.0.0.0', 8001))  #绑定IP和端口
     6 server.listen(5)                #监听端口
     7 
     8 
     9 all_connection = []             #保存已经连接的客户
    10 while True:
    11     #只管连接的事情
    12     try:
    13         conn, addr = server.accept()    # 建立连接,没有就抛出异常
    14         conn.setblocking(False)         #设置非阻塞
    15         print('用户连接:', addr)
    16         all_connection.append(conn)
    17     except Exception as e:
    18         pass
    19 
    20 
    21     #处理已经连接用户的消息
    22     handle = all_connection.copy()  #完全拷贝了列表
    23     for connection in handle:
    24         try:
    25             recv_data = connection.recv(1024)
    26             if recv_data:
    27                 print(recv_data.decode())
    28                 connection.send(recv_data)
    29             else:                               #客户端消息处理完了,已经断开了连接
    30                 print('断开连接', connection)
    31                 connection.close()
    32                 all_connection.remove(connection)       #从客户列表里移除断开连接的客户
    33         except Exception as e:
    34             pass

    03 epoll服务端

    特征:1对多,通知机制,非阻塞,占用资源少;
    epoll:注册惰性事件回调。
     1 import selectors #调用epoll的模块
     2 import socket
     3 
     4 epoll = selectors.EpollSelector()   #生成一个epoll
     5 server = socket.socket()            #生成套接字
     6 server.bind(('', 8082))  #参数1‘’与‘0.0.0.0’等价,表示ip都可接入
     7 server.listen(100)
     8 
     9 
    10 #回调函数
    11 def create_conneciton(server):
    12     #百分百有人连接,不会阻塞
    13     conn, addres = server.accept()  #生成对等连接套接字
    14 
    15 
    16     #处理消息的函数注册
    17     epoll.register(conn, selectors.EVENT_READ, read_data)
    18     return conn
    19 
    20 
    21 
    22 #回调函数   处理消息
    23 def read_data(conn):
    24 
    25     data = conn.recv(1024)
    26     if data:
    27         print(data)
    28         conn.send(data)
    29     else:
    30         epoll.unregister(conn)  #删掉注册事件
    31 
    32 
    33 #1
    34 #把监听套接字和生成对等套接字的函数注册到read事件(有用户连接)
    35 epoll.register(server, selectors.EVENT_READ, create_conneciton)
    36 
    37 
    38 #2
    39 while True:      #事件循环
    40     events = epoll.select()  #去操作系统查询
    41 
    42     for key,mask in events:
    43         sock = key.fileobj      #连接客户端的套接字
    44         callback = key.data     #回调函数
    45 
    46         #read_data(conn),   create_conneciton(server)
    47         callback(sock)      #调用函数

    04 客户端

    测试服务端。
     1 import socket
     2 
     3 client = socket.socket()
     4 client.connect(('127.0.0.1', 8082))
     5 
     6 while True:
     7     data = input('输入数据:')
     8     client.send(data.encode())
     9     recv_data = client.recv(1024)
    10     print(recv_data.decode())
  • 相关阅读:
    Linux下绑定网卡的操作记录
    迭代器、生成器、装饰器
    python二模块之装饰器
    python实现 --工资管理系统
    投票接口压测
    Mysql exists和in
    Django处理一个请求的过程
    快速排序 Python实现
    宿主机访问ubuntu虚拟机内的Django应用,访问不到的解决办法
    四、Git分支管理
  • 原文地址:https://www.cnblogs.com/Selling-fish-bears/p/9316890.html
Copyright © 2020-2023  润新知