Python3并发编程篇之IO多路复用selectors模块

参考源

selectors模块

介绍

selectors模块帮我们选择当前操作系统平台下最合适的IO多路复用机制

  • 有epoll就用epoll
  • 有poll就用poll
  • 有select就用select

导入

selectors模块是一个内置模块, 直接导入即可.

import selectors

实现

Server端

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""IO多路复用之selectors模块

selectors模块帮我们选择当前操作系统平台下最合适的IO多路复用机制
    有epoll就用epoll
    有poll就用poll
    有select就用select

Server端
"""

import selectors
import socket


def to_accept(sock, mask):
    conn, addr = sock.accept()
    conn.setblocking(False)
    sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_read)


def to_read(conn, mask):
    try:
        recvs = conn.recv(1024)
        if not recvs:
            sel.unregister(fileobj=conn)
            conn.close()
            return
        print(recvs.decode(encoding='utf-8'))
        sel.unregister(fileobj=conn)
        wdict[conn] = b'%s' % (recvs, )
        sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_write)
    except ConnectionResetError:
        sel.unregister(fileobj=conn)
        conn.close()
        return


def to_write(conn, mask):
    # print(mask)  # EVENT_READ 值为1, EVENT_WRITE 值为2
    conn.sendall(wdict.get(conn))
    wdict.pop(conn)
    sel.unregister(fileobj=conn)
    sel.register(fileobj=conn, events=selectors.EVENT_READ, data=to_read)


sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

sk.bind(('', 8080))

sk.listen(32)

sk.setblocking(False)  
sel = selectors.DefaultSelector()

sel.register(fileobj=sk, events=selectors.EVENT_READ, data=to_accept)

wdict = dict()

while 1:
    events = sel.select(timeout=None)
    for sel_obj, mask in events:
        callback = sel_obj.data
        callback(sel_obj.fileobj, mask)

Client端

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""IO多路复用之selectors模块

Client端
"""

import socket
import threading


def my_client():
    sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    sk.connect(('localhost', 8080))
    while 1:
        sk.send(b'hi')
        msg = sk.recv(1024)
        print(msg)


for i in range(10):
    threading.Thread(target=my_client).start()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值