io多路复用

首先需要明确的是,linux有五类io模型
1.阻塞
2.非阻塞
3.io多路复用
4.事件驱动
5.异步
(ps:这里需要的点是:io多路复用和非阻塞是并列的关系哦~,不过一般来说io多路复用都是和非阻塞搭配使用的。)

最容易理解的是阻塞。一次网络io时,C端发出请求,S端收到。当C端发出一个请求,进行io时,就不能进行其他操作了,需要同步的等待结果的返回。

当使用io多路复用时,有多个C端同时发送请求,这些IO操作会被selector(epoll,kqueue)给暂时挂起,入内存队列。此时S端可以自己选择什么时候读取、处理这些io,也就是说S端可以同时hold住多个io。

epoll伪代码:

while True:
        sel_results = select_ready() # block
        for r in sel_results:
                deal_with_it_util_not_available()
image.png
image.png

挂个demo

# coding: utf-8

# blocking / epoll io client

import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()  # Should be ready,拷贝到内存空间,并分配一个新的socket,给当前接入的请求
    print('accepted', addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read) # 将这个sokcet注册到 sel,也就是sel也可以开始监听这个sock,并注册回调,等待下次轮训

def read(conn, mask):
    data = conn.recv(1000)  # 下次轮训,执行这个回调
    if data:
        print('echoing', conn)
        conn.send(data) # 回传数据给请求方。
        print('send over', conn)

    else:
        print('closing', conn) 
        sel.unregister(conn) # 请求结束,删除socket监听
        conn.close()

sock = socket.socket() # 绑定一个socket
sock.bind(('localhost', 12325))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept) # selector注册监听这个socket。可以把这个sokcet当作一个流。一直监听的只有这个接收请求的socket
i = 1
import time
while True: # 轮训sel的ready事件
    events = sel.select() 
    time.sleep(10)
    for key, mask in events: 
        callback = key.data
        callback(key.fileobj, mask)
    print('this is ', i)
    i += 1

输出结果:

*accepted* ('127.0.0.1', 34154)
this is  1
*accepted* ('127.0.0.1', 34550)
echoing <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12325), raddr=('127.0.0.1', 34154)>
send over <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12325), raddr=('127.0.0.1', 34154)>
this is  2
*accepted* ('127.0.0.1', 34732)
echoing <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12325), raddr=('127.0.0.1', 34550)>
send over <socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12325), raddr=('127.0.0.1', 34550)>
this is  3
echoing <socket.socket fd=7, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12325), raddr=('127.0.0.1', 34732)>
send over <socket.socket fd=7, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12325), raddr=('127.0.0.1', 34732)>
this is  4

可以观察到,sel.select()每次选出一个sock,然后对这个sock上的事件进行处理。所以io多路复用,在没有用特殊异步api的情况下,还是同步的操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容