IO多路複用技術

IO多路複用

select 多路複用技術

  1. 32系統只能1024個鏈接 64位 2048個python

  2. 採用輪詢機制,當併發大的時候,就會崩了緩存

POLL只是突破了鏈接的限制併發

上代碼:app

from socket import *
import select


def main():
    # 建立對象
    tcp_server = socket(AF_INET, SOCK_STREAM)
    # 綁定地址
    tcp_server.bind(('', 8888))
    # 將主動模式設置爲被動模式
    tcp_server.listen(5)
    # 初始化一個列表
    server_lists = [tcp_server]  # 將初始socket對象添加至列表中

    while True:
        sockets, _, _ = select.select(server_lists, [], [])
        for obj in sockets:
            if obj == tcp_server:
                # 建立新的鏈接
                new_socket, client_info = obj.accept()
                # 將新的new_socket對象添加至列表
                server_lists.append(new_socket)
                # 打印鏈接信息
                print(f'來自{client_info} 鏈接成功!')

            else:
                # 接收數據
                raw_data = obj.recv(1024)
                # 注意: 這個地方不能使用死循環,不然會致使阻塞狀況,同一時總能一個客戶端通訊,其餘客戶端將阻塞排隊中,當前面斷開是,後面的講能夠繼續通訊
                if raw_data:
                    # 打印數據
                    print(f'接收到數據: {raw_data.decode("gb2312")}')
                else:
                    # 內容爲空 移出鏈接信息
                    server_lists.remove(obj)
                    obj.close()


if __name__ == '__main__':
    main()

epoll 多路複用技術( 高併發 )

什麼是epoll多路複用?

poll已實現無數鏈接 輪詢socket

epoll 改爲事件通知tcp

只能在Linux上使用 不能在window使用高併發

上代碼:code

from socket import *
import select


def main():
    # 建立對象
    tcp_socket = socket(AF_INET, SOCK_STREAM)
    # 綁定地址
    tcp_socket.bind(('', 8888))
    # 將主動模式設置爲被動模式
    tcp_socket.listen(5)
    # 建立epoll
    epoll = select.epoll()
    # 把被動套接字添加至監聽讀狀態
    epoll.register(tcp_socket.fileno(), select.EPOLLIN)
    # 聲明一個字典 用來存新建立套接字
    new_sockets = {}
    client_infos = {}
    while True:
        epoll_list = epoll.poll()
        for fd, _ in epoll_list:
            if fd == tcp_socket.fileno():
                # 建立新的鏈接
                new_socket, client_info = tcp_socket.accept()
                # 把新對象添加至監聽
                epoll.register(new_socket.fileno(), select.EPOLLIN)
                # 添加至字典
                new_sockets[new_socket.fileno()] = new_socket
                client_infos[client_info] = client_info
                print(f'來自{client_info} 鏈接成功!')
            else:
                # 接收數據
                raw_data = new_sockets[fd].recv(1024)
                # 判斷是否有數據
                if raw_data:
                    print(f'來自{client_info}的信息: {raw_data.decode("gb2312")}')
                else:
                    print('客戶端已斷開!')
                    # 客戶端已關閉
                    new_sockets[fd].close()
                    # 註銷監聽隊列
                    epoll.unregister(fd)
                    # 移除字典
                    del new_sockets[fd]
                    del client_infos


if __name__ == '__main__':
    main()

專業名詞

  1. IO阻塞:Input output 輸入輸出 一寫有一個緩存的東西 必定是讀寫操做 去緩存區取東西,若是沒有就等待
  2. IO非阻塞:去緩存區取東西,無論有沒有,必需得取,取到就正常,不然就異常
  3. 輪詢:每一個人都要問一遍,很是耗時
  4. 事件通知機制:epoll 採用這個機制
相關文章
相關標籤/搜索