【问题标题】:Read stdin non-blocking读取标准输入非阻塞
【发布时间】:2018-01-25 00:44:31
【问题描述】:

我正在编写一个 Vala 程序,它使用标准输出和标准输入作为子进程生成,用于与父级进行消息传输。在异步方法中,我调用 read_stdin(sb) 来检查传入消息。我尝试了各种标准输入方法,例如gets 和getc,但它们似乎都阻塞了'\n' 换行符。我需要读取所有可用的字符并立即返回(非阻塞)。

    const int STDIN_BUF_SIZE=1024;
    char[] stdin_buffer;
    bool read_stdin (StringBuilder sb) {
        int iPos=0;
        int c;
        int buf_size=STDIN_BUF_SIZE-1;
        // Char by char:
        while (true) {
            c = stdin.getc ();
            if(c ==  GLib.FileStream.EOF) break;
            stdin_buffer[iPos]=(char)c;
            iPos++;
            if ((char)c=='\n'||iPos==buf_size){
                break;
                }
            }
        if(iPos>0){
            stdin_buffer[iPos]=0;
            sb.append((string)stdin_buffer);
            return true;
            }
        return false;
    }

stdin 可以用于非阻塞 IO 还是我需要创建类似...

DataInputStream stdin_reader = new DataInputStream(stdin);

【问题讨论】:

    标签: vala


    【解决方案1】:

    您使用“非阻塞”一词,但我认为这并不意味着您认为它的含义。如果非阻塞 I/O 是您真正想要的,那么简单地用 O_NONBLOCK 打开 /dev/stdin 会很容易。在这种情况下,getc 将立即返回 EOF,直到有可用数据为止。

    AFAICT,您实际上想要的是阻止 getc 调用,直到有新数据可用,然后立即返回。从技术上讲,这就是正在发生的事情。问题是终端应用程序通常会缓冲数据直到换行,这解释了为什么您可以编辑数据而没有任何编辑出现在您的应用程序中;继续,尝试在您的程序中输入“AB”,您将看到的将是“B\n”。

    基本上,您需要使用curses library。 Vala 包含一个 curses.vapi,因此您只需要链接到相关库(可能是 ncurses)并将 --pkg curses 添加到您的 valac 调用中,您就可以开始使用了。 IIRC 相关函数是getch,但是我已经很久没有做过任何诅咒编程了。

    【讨论】:

    • 始终在尊重的详细解释(包括替代方案)方面付出巨大努力。它具有教育意义,非常感谢!谢谢!
    • 如果你想比curses低一点,你应该阅读原始模式和熟模式或一般终端模式之间的区别。 en.wikipedia.org/wiki/Terminal_mode
    • 哦,这里有一个关于如何在 C 中构建文本编辑器的教程,这可能也很有趣:viewsourcecode.org/snaptoken/kilo
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 2011-12-27
    • 2010-11-19
    • 2018-07-26
    • 1970-01-01
    相关资源
    最近更新 更多