非阻塞IO - 编程模型

时间:2017-10-27 00:26:54

标签: java python multithreading io nonblocking

在非阻塞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 的线程执行另一个CPU限制在同一个线程中的任务,同时?

2 个答案:

答案 0 :(得分:1)

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

在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类有类似的方法,例如selectNow()select(long timeout)

答案 1 :(得分:0)

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

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

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