Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
February 14, 2014 Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
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 |
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas | 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 |
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas | 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 :D
Maybe 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();
|
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to nazriel | On Friday, 14 February 2014 at 19:09:06 UTC, nazriel wrote: > 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 :D > > Maybe try closing stdin pipe after you are done writing to child. > > pipes.stdin.close(); > Ok, nvm. You are reading from child after each write. So naa, closing pipe won't do it. So we are back to flushing :) > Or try flushing after writing to childs stdin, IIRC: > > pipes.stdin.flush(); |
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas | 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
|
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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 works
Impressive reply speed! :)
However calling pipes.stdin.flush() immediately after writeln did
not seem to work.
|
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas | 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:
>> 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
>
> Impressive reply speed! :)
>
> However calling pipes.stdin.flush() immediately after writeln did
> not seem to work.
You must also flush from the child process -- it too is connected to a pipe and not a console.
-Steve
|
February 14, 2014 Re: Reading input from piped stdin. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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:
>
>> 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
Ah, had to add after both writelns. Looks like that solved it.
Thanks!
|
Copyright © 1999-2021 by the D Language Foundation