如何测试stdin在julia中是否有可用的输入?

如何测试stdin在julia中是否有可用的输入?,julia,polling,Julia,Polling,我想在短时间内检测stdin上是否有输入,并以任何方式继续执行,结果存储在Bool中。(我的真正目标是在终端中运行的模拟上实现一个暂停按钮。第二次按键应该取消暂停程序,并继续执行。)我曾尝试使用poll\u fd,但在stdin上不起作用: julia> FileWatching.poll_fd(stdin, readable=true) ERROR: MethodError: no method matching poll_fd(::Base.TTY; readable=true) 有

我想在短时间内检测
stdin
上是否有输入,并以任何方式继续执行,结果存储在
Bool
中。(我的真正目标是在终端中运行的模拟上实现一个暂停按钮。第二次按键应该取消暂停程序,并继续执行。)我曾尝试使用
poll\u fd
,但在
stdin
上不起作用:

julia> FileWatching.poll_fd(stdin, readable=true)
ERROR: MethodError: no method matching poll_fd(::Base.TTY; readable=true)
有没有一种方法对朱莉娅有效?我已经找到了,并且考虑过通过PyCall使用它,但我正在寻找

  • 一种干净、纯粹的方式;及
  • 一种不会对抗或潜在干扰julia使用libuv的方式
  • 下面是一个示例用法。请注意,如果捕获键盘,您还需要自己处理Ctrl+C(在本例中,仅检查块的第一个字节)

    如果要完全异步运行,请将
    @async
    放在
    while
    循环前面。然而,如果在这种情况下没有更多的代码,这个程序就会退出

    import REPL
    term = REPL.Terminals.TTYTerminal("xterm",stdin,stdout,stderr)
    REPL.Terminals.raw!(term,true)
    Base.start_reading(stdin)
    
    while (true)
        sleep(1)
        bb = bytesavailable(stdin)
        if bb > 0
            data = read(stdin, bb)
            if data[1] == UInt(3)
                println("Ctrl+C - exiting")
                exit()
            end
            println("Got $bb bytes: $(string(data))")
        end
    end
    

    根据@Przemyslaw Szufel的回答,这里有一个完整的解决方案,允许按键暂停/取消暂停循环的迭代:

    import REPL
    term = REPL.Terminals.TTYTerminal("xterm",stdin,stdout,stderr)
    REPL.Terminals.raw!(term,true)
    Base.start_reading(stdin)
    
    function read_and_handle_control_c()
        b = bytesavailable(stdin)
        @assert b > 0
        data = read(stdin, b)
        if data[1] == UInt(3)
            println("Ctrl+C - exiting")
            exit()
        end
        nothing
    end
    
    function check_for_and_handle_pause()
        if bytesavailable(stdin) > 0
            read_and_handle_control_c()
            while bytesavailable(stdin) == 0
                sleep(0.1)
            end
            read_and_handle_control_c()
        end
        nothing
    end
    
    while true
        # [do stuff]
        sleep(0.05)
        check_for_and_handle_pause()
    end
    

    这有点不太理想,因为它要求进程即使在暂停时也要定期醒来,但它仍然实现了我的目标。

    bytesavable(stdin)
    即使在按下多个键后也返回
    0
    。我现在想知道是否有办法禁用libuv的输入缓冲区。谢谢
    bytesavable(stdin)
    现在返回可用字节数。但这是以Ctrl+C不再中断该过程为代价的。此外,我正在尝试找出如何在字节可用时同步读取/清除(
    read(stdin)
    不起作用)。我为您编写了完整的代码并更新了答案,但如果您想添加其他功能,请在StackOverflow上问一个单独的问题,julia 1.5现在已发布,我相信现在使用
    Base.exit on\u sigint可以更简洁地启用Ctrl+C中断
    
    import REPL
    term = REPL.Terminals.TTYTerminal("xterm",stdin,stdout,stderr)
    REPL.Terminals.raw!(term,true)
    Base.start_reading(stdin)
    
    function read_and_handle_control_c()
        b = bytesavailable(stdin)
        @assert b > 0
        data = read(stdin, b)
        if data[1] == UInt(3)
            println("Ctrl+C - exiting")
            exit()
        end
        nothing
    end
    
    function check_for_and_handle_pause()
        if bytesavailable(stdin) > 0
            read_and_handle_control_c()
            while bytesavailable(stdin) == 0
                sleep(0.1)
            end
            read_and_handle_control_c()
        end
        nothing
    end
    
    while true
        # [do stuff]
        sleep(0.05)
        check_for_and_handle_pause()
    end