使用D控制交互式进程

使用D控制交互式进程,d,D,我有一个程序,它等待一行标准输入,然后在处理它之后(这需要相对较长的时间),发出一个答案。程序将接受输入,直到输入流关闭 我怎样才能从D控制那个程序?换句话说,我怎么能 给子进程一行标准输入 等待子进程应答 重复,直到我用尽了我想给它的输入 我尝试了以下代码,但毫不奇怪,它会等待子进程完全完成,然后立即打印输出: module main; import std.file; import std.path; import std.process; import std.stdio; void

我有一个程序,它等待一行标准输入,然后在处理它之后(这需要相对较长的时间),发出一个答案。程序将接受输入,直到输入流关闭

我怎样才能从D控制那个程序?换句话说,我怎么能

  • 给子进程一行标准输入
  • 等待子进程应答
  • 重复,直到我用尽了我想给它的输入
  • 我尝试了以下代码,但毫不奇怪,它会等待子进程完全完成,然后立即打印输出:

    module main;
    
    import std.file;
    import std.path;
    import std.process;
    import std.stdio;
    
    void main(string[] args)
    {
        string[] inputs = ["test string 1", "test string 2"];
    
        auto pipes = pipeProcess(buildPath(getcwd(), "LittleTextProcessingApp"), Redirect.all);
        scope(exit) wait(pipes.pid);
    
        foreach(input; inputs)
        {
            pipes.stdin.writeln(input);
        }
        pipes.stdin.close;
    
        foreach(line; pipes.stdout.byLine)
        {
            writeln(line);
        }
    }
    
    也就是说,它在延迟一秒钟后打印

    以下内容是500毫秒前输入的:测试字符串1
    以下内容是500毫秒前输入的:测试字符串2

    理想的行为是打印

    以下内容是500毫秒前输入的:测试字符串1

    半秒钟后,第二行500毫秒后

    我作为子进程测试的程序的源代码如下:

    module main;
    
    import std.stdio;
    import core.thread;
    
    void main(string[] args)
    {
        foreach(input; stdin.byLine)
        {
            auto duration = 500.msecs;
            stderr.writefln("Doing something for %s....", duration);
            Thread.sleep(duration);
            writefln("The following was input %s ago: %s", duration, input);
        }
    }
    

    罪魁祸首是子进程。 在
    writefln
    之后,默认情况下不会刷新输出。 相反,它被保存在一个缓冲区中(几千字节长)。 这是一种常见的技术(并非特定于硬盘),它可以极大地提高速度,例如,当以大量的几个字节块将一个大文件写入硬盘时

    要刷新缓冲区,请在每次希望立即显示输出时使用stdout.flush()。
    在子示例的代码中的最后一个
    writefln
    之后添加该行可以修复示例中的情况。

    我想为了安全起见,应该在子进程和父进程中都使用stdout.flush()。(至少在Xamarin中使用内部输出缓冲区是必要的,这就是我正在使用的。)我注意到,当不直接在shell中运行时,D会使缓冲区填满相当长的一段时间,直到实际刷新为止。