非阻塞 IO - 编程模型

Non blocking IO - Programming model

在非阻塞IO编程模型中,线程阻塞在数据可用通道上,如下图,

在python,

while True:
    readers, _, _ = select.select([sys.stdin, sock], [], []) # blocked select()
    for reader in readers:
        if reader is sock:
            print(sock.recv(1000).decode('utf-8'))
        else:
            msg = sys.stdin.readline()
            sock.send(msg.encode('utf-8'))

在java,

     public void run() {
        while(true){
            try{
                executeCycle();
            } catch(IOException e){
                e.printStackTrace();
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public void executeCycle() throws IOException {
        takeNewSockets();
        readFromSockets();
        writeToSockets();
    }

在非阻塞IO编程模型中,执行流程一般遵循无限循环模式,主要(仅)负责找到数据可用通道(就绪)并使用可用通道执行IO。


在所有通道都忙(持续一段时间)的情况下,非阻塞IO编程模型是否允许执行nio的线程with/without无限循环还要同时在同一个线程中执行另一个 CPU 绑定任务?

这些 API 通常允许您为选择步骤指定超时。也就是说,等待任何通道准备就绪的时间量,如果在超时时间内没有通道准备就绪,则返回一个空集。您还可以立即进行 returns 的非块选择。

在python中:

while True:
    readers, _, _ = select.select([sys.stdin, sock], [], [], 0) # non-block select
    # readers could be an empty list
    if readers:
        for reader in readers:
            if reader is sock:
                print(sock.recv(1000).decode('utf-8'))
            else:
                msg = sys.stdin.readline()
                sock.send(msg.encode('utf-8'))
    else:
        some_other_operations() # but only when no channel is ready

Java 的 Selector class 有类似 selectNow()select(long timeout) 的方法,您可以使用。

我认为在同一线程中同时执行其他操作并不容易。您必须调用代码来执行其他操作。您如何保证控制 returns 在合理的时间范围内检查输入?

但是如果您有单独的线程来处理其他操作,那么只要有可用资源,运行时间系统就会将这些线程分配给 运行。如果您在繁忙的循环中使用 Thread.sleep(100) 之类的东西,那么这将确保这个繁忙的循环不会耗尽太多资源,以至于其他东西可以同时 运行 而无需你必须做一些特别的事情。

但是,您必须确保以线程安全的方式处理在输入检查器线程和其他线程之间共享的任何资源。