为什么IO-multiplexing要与非阻塞IO一起使用

先看一个例子IO-multiplexing+阻塞IO

首先需要明确的是IO复用是同步的,并不是异步的

IO-multiplexing+阻塞IO

程序实现了Netcat的简单功能

#!/usr/bin/python

import os
import select
import socket
import sys

def relay(sock):
    poll = select.poll()
    poll.register(sock, select.POLLIN)
    poll.register(sys.stdin, select.POLLIN)

    done = False
    while not done:
        events = poll.poll(10000)  # 10 seconds
        for fileno, event in events:
            if event & select.POLLIN:
                if fileno == sock.fileno():
                    data = sock.recv(8192)
                    if data:
                        sys.stdout.write(data)
                    else:
                        done = True
                else:
                    assert fileno == sys.stdin.fileno()
                    data = os.read(fileno, 8192)
                    if data:
                        sock.sendall(data)
                    else:
                        sock.shutdown(socket.SHUT_WR)
                        poll.unregister(sys.stdin)


def main(argv):
    if len(argv) < 3:
        binary = argv[0]
        print "Usage:\n  %s -l port\n  %s host port" % (argv[0], argv[0])
        return
    port = int(argv[2])
    if argv[1] == "-l":
        # server
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind(('', port))
        server_socket.listen(5)
        (client_socket, client_address) = server_socket.accept()
        server_socket.close()
        relay(client_socket)
    else:
        # client
        sock = socket.create_connection((argv[1], port))
        relay(sock)


if __name__ == "__main__":
    main(sys.argv)

试验1

[root@localhost python]# python netcat.py localhost 1234 > /dev/null

//chargen会打印吞吐量,write hole,只输出数据,不接受数据
[root@localhost tpc]# ./chargen -l 1234
Accepting... Ctrl-C to exit
accepted no. 1 client
171.688 MiB/s
166.395 MiB/s
186.773 MiB/s
240.171 MiB/s
235.967 MiB/s
130.270 MiB/s
18.044 MiB/s

client端
python netcat.py localhost 1234 > /dev/null

试验2

先在./chargen -l 1234命令行下敲几个输入,如下
[root@localhost tpc]# ./chargen -l 1234
Accepting... Ctrl-C to exit
accepted no. 1 client
171.688 MiB/s
166.395 MiB/s
186.773 MiB/s
240.171 MiB/s
235.967 MiB/s
130.270 MiB/s
18.044 MiB/s



accepted no. 2 client
11.838 MiB/s
。。
//这里chargen不打印了,阻塞了
client端
 python netcat.py localhost 1234 < /dev/zero > /dev/null

这里用strace看一下netcat.py阻塞在了sendto()上。
用netstat查看下

[root@localhost david]# netstat -tnp | grep 1234
tcp   5966266 4188544 127.0.0.1:50776         127.0.0.1:1234          ESTABLISHED 5620/python         
tcp   975372 4169984 127.0.0.1:1234          127.0.0.1:50776         ESTABLISHED 5612/./chargen 

netcat.py阻塞在了write上,其发送缓冲区满了;因此chargen也会阻塞在write上。

再看一个thread-per-connection的netcat,并没有影响,chargen任然在打印

[root@localhost david]# netstat -tnp | grep 1234
tcp        0 4188544 127.0.0.1:50778         127.0.0.1:1234          ESTABLISHED 5802/./netcat       
tcp   975372      0 127.0.0.1:1234          127.0.0.1:50778         ESTABLISHED 5612/./chargen 

netcat继续再收,虽然阻塞在发送上(可从上面看出netcat的发送缓冲区满了),但是任然在接受。

注意IO复用如果和阻塞IO一起使用了,一旦真的阻塞,就会把此事件循环中管的别的事件挡住了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值