Interactive process control using D

I have a program that expects a line of standard input, and then, after processing it (which takes a relatively long time), emits a response. The program will receive input until the input stream closes.

How can I control this program from D? In other words, how could I

  • Give the child process a standard input string.
  • Wait for the child process to respond.
  • Repeat until I exhaust the inputs that I want to give him.

I tried the following code, but it is not surprising that it waits for the complete process of the child process to complete and then prints the output immediately:

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); } } 

That is, it prints after a one second delay

The following was introduced 500 ms ago: test line 1
The following was introduced 500 ms ago: test line 2

The desired behavior is that it prints

Below was entered 500 ms ago: test line 1

after half a second, and the second line - 500 ms later.

The source code for the program that I am testing as a child process is as follows:

 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); } } 
+5
source share
1 answer

The culprit is a child process. After writefln , the default output is not cleared. Instead, it is stored in a buffer (several kilobytes long). This is a common technique (not specific to D), which can significantly increase the speed, for example, when writing a large file to the hard disk in a large number of several byte blocks.

To clear the buffer, use stdout.flush() every time you want the result to be displayed immediately. Adding this line after the last writefln in the example of your child code corrects the situation in the example.

+4
source

Source: https://habr.com/ru/post/1240228/


All Articles