digitalmars.D.learn - Reading input from piped stdin.
- Thomas (37/37) Feb 14 2014 I'm new to D, and I find it quite enjoyable so far.
- Adam D. Ruppe (7/7) Feb 14 2014 Just a quick look, but I betcha it has to do with buffering.
- Thomas (4/11) Feb 14 2014 Impressive reply speed! :)
- Steven Schveighoffer (4/17) Feb 14 2014 You must also flush from the child process -- it too is connected to a
- nazriel (5/43) Feb 14 2014 Maybe try closing stdin pipe after you are done writing to child.
- nazriel (5/58) Feb 14 2014 Ok, nvm.
- Steven Schveighoffer (11/21) Feb 14 2014 stdin and stdout are buffered streams. Buffered streams in D only flush ...
- Thomas (4/32) Feb 14 2014 Ah, had to add after both writelns. Looks like that solved it.
I'm new to D, and I find it quite enjoyable so far. I have however stumbled upon a problem which I can't seem to figure out. I am trying to make a program that creates a child process, writes something to the child process stdin and reading from its stdout. I am going to use it later for testing out process pair redundancy. Appearently the child blocks at "s = stdin.readln()". If I remove all writing to the child, and instead just read its output, everything works fine. My code is attached below: import std.process,std.stdio,std.getopt,core.thread; void main(string[] args){ bool backup = false; getopt(args, "backup", &backup); writeln("Something worked!"); string s = "test"; if (backup){ writeln("Backup up & running"); while(true){ s = stdin.readln(); writeln(s); } } auto pipes = pipeProcess(["./pipetest", "--backup"], Redirect.all); for(int j = 0; j<5; j++){ writeln(j); pipes.stdin.writeln(j); writeln(pipes.stdout.readln()); Thread.sleep(500.msecs); } while(true){} } If anyone could spot what rudimentary mistake I have done, I would greatly appreciate it. Alternatively, suggesting another way to implement inter-process communication would also be appreciated :D
Feb 14 2014
Just a quick look, but I betcha it has to do with buffering. After writing the line to the pipe, call the flush() method on the output pipe and see what happens there. (Pipes buffer differently than regular output so this is a common mixup, especially with IDEs which communicate with stdout via pipes normally!) let me know if it works
Feb 14 2014
On Friday, 14 February 2014 at 19:08:20 UTC, Adam D. Ruppe wrote:Just a quick look, but I betcha it has to do with buffering. After writing the line to the pipe, call the flush() method on the output pipe and see what happens there. (Pipes buffer differently than regular output so this is a common mixup, especially with IDEs which communicate with stdout via pipes normally!) let me know if it worksImpressive reply speed! :) However calling pipes.stdin.flush() immediately after writeln did not seem to work.
Feb 14 2014
On Fri, 14 Feb 2014 14:16:23 -0500, Thomas <sitronvask gmail.com> wrote:On Friday, 14 February 2014 at 19:08:20 UTC, Adam D. Ruppe wrote:You must also flush from the child process -- it too is connected to a pipe and not a console. -SteveJust a quick look, but I betcha it has to do with buffering. After writing the line to the pipe, call the flush() method on the output pipe and see what happens there. (Pipes buffer differently than regular output so this is a common mixup, especially with IDEs which communicate with stdout via pipes normally!) let me know if it worksImpressive reply speed! :) However calling pipes.stdin.flush() immediately after writeln did not seem to work.
Feb 14 2014
On Friday, 14 February 2014 at 19:05:02 UTC, Thomas wrote:I'm new to D, and I find it quite enjoyable so far. I have however stumbled upon a problem which I can't seem to figure out. I am trying to make a program that creates a child process, writes something to the child process stdin and reading from its stdout. I am going to use it later for testing out process pair redundancy. Appearently the child blocks at "s = stdin.readln()". If I remove all writing to the child, and instead just read its output, everything works fine. My code is attached below: import std.process,std.stdio,std.getopt,core.thread; void main(string[] args){ bool backup = false; getopt(args, "backup", &backup); writeln("Something worked!"); string s = "test"; if (backup){ writeln("Backup up & running"); while(true){ s = stdin.readln(); writeln(s); } } auto pipes = pipeProcess(["./pipetest", "--backup"], Redirect.all); for(int j = 0; j<5; j++){ writeln(j); pipes.stdin.writeln(j); writeln(pipes.stdout.readln()); Thread.sleep(500.msecs); } while(true){} } If anyone could spot what rudimentary mistake I have done, I would greatly appreciate it. Alternatively, suggesting another way to implement inter-process communication would also be appreciated :DMaybe try closing stdin pipe after you are done writing to child. pipes.stdin.close(); Or try flushing after writing to childs stdin, IIRC: pipes.stdin.flush();
Feb 14 2014
On Friday, 14 February 2014 at 19:09:06 UTC, nazriel wrote:On Friday, 14 February 2014 at 19:05:02 UTC, Thomas wrote:Ok, nvm. You are reading from child after each write. So naa, closing pipe won't do it. So we are back to flushing :)I'm new to D, and I find it quite enjoyable so far. I have however stumbled upon a problem which I can't seem to figure out. I am trying to make a program that creates a child process, writes something to the child process stdin and reading from its stdout. I am going to use it later for testing out process pair redundancy. Appearently the child blocks at "s = stdin.readln()". If I remove all writing to the child, and instead just read its output, everything works fine. My code is attached below: import std.process,std.stdio,std.getopt,core.thread; void main(string[] args){ bool backup = false; getopt(args, "backup", &backup); writeln("Something worked!"); string s = "test"; if (backup){ writeln("Backup up & running"); while(true){ s = stdin.readln(); writeln(s); } } auto pipes = pipeProcess(["./pipetest", "--backup"], Redirect.all); for(int j = 0; j<5; j++){ writeln(j); pipes.stdin.writeln(j); writeln(pipes.stdout.readln()); Thread.sleep(500.msecs); } while(true){} } If anyone could spot what rudimentary mistake I have done, I would greatly appreciate it. Alternatively, suggesting another way to implement inter-process communication would also be appreciated :DMaybe try closing stdin pipe after you are done writing to child. pipes.stdin.close();Or try flushing after writing to childs stdin, IIRC: pipes.stdin.flush();
Feb 14 2014
On Fri, 14 Feb 2014 14:05:01 -0500, Thomas <sitronvask gmail.com> wrote:I'm new to D, and I find it quite enjoyable so far. I have however stumbled upon a problem which I can't seem to figure out. I am trying to make a program that creates a child process, writes something to the child process stdin and reading from its stdout. I am going to use it later for testing out process pair redundancy. Appearently the child blocks at "s = stdin.readln()". If I remove all writing to the child, and instead just read its output, everything works fine. My code is attached below:stdin and stdout are buffered streams. Buffered streams in D only flush on newline when they are attached to a console (terminal window). Otherwise, they wait until the buffer is full before flushing. Buffer is probably about 4096 bytes. What is likely happening is that you are writing, it's going into the buffer, but not flushing, and then you are waiting for the response (which likely is also not flushing from the child process). Try adding flushes after each writeln. BTW, this is not really a D problem, you would have the same issue in C. -Steve
Feb 14 2014
On Friday, 14 February 2014 at 19:12:24 UTC, Steven Schveighoffer wrote:On Fri, 14 Feb 2014 14:05:01 -0500, Thomas <sitronvask gmail.com> wrote:Ah, had to add after both writelns. Looks like that solved it. Thanks!I'm new to D, and I find it quite enjoyable so far. I have however stumbled upon a problem which I can't seem to figure out. I am trying to make a program that creates a child process, writes something to the child process stdin and reading from its stdout. I am going to use it later for testing out process pair redundancy. Appearently the child blocks at "s = stdin.readln()". If I remove all writing to the child, and instead just read its output, everything works fine. My code is attached below:stdin and stdout are buffered streams. Buffered streams in D only flush on newline when they are attached to a console (terminal window). Otherwise, they wait until the buffer is full before flushing. Buffer is probably about 4096 bytes. What is likely happening is that you are writing, it's going into the buffer, but not flushing, and then you are waiting for the response (which likely is also not flushing from the child process). Try adding flushes after each writeln. BTW, this is not really a D problem, you would have the same issue in C. -Steve
Feb 14 2014