I'm using pipes to communicate two Prolog processes and every time I reached a read/2
predicate to read a message from my pipe, the program blocked and remained like that. I couldn't understand why that happened (I tried with extremely simple programs) and at the end I realized three things:
- Every time I use
write/2
to send a message, the sender process must end that message with.\n
. If the message does not end like this, the receiver process will get stuck at theread/2
predicate. - If the sender does not flush the output, the message therefore is not left in the pipe buffer. It may seem obvious but it wasn't for me at the beginning.
- Although when the message is not flushed the
read/2
is blocking,wait_for_input/3
is not blocking at all, so no need forflush_output/1
in such case.
Examples:
This does not work:
example1 :-
pipe(R,W),
write(W,hello),
read(R,S). % The program is blocked here.
That one won't work either:
example2 :-
pipe(R,W),
write(W,'hello.\n'),
read(R,S). % The program is blocked here.
While these two, do work:
example3 :-
pipe(R,W),
write(W,'hello.\n'),
flush_output(W),
read(R,S).
example4 :-
pipe(R,W),
write(W,'hello.\n'),
wait_for_input([W],L,infinite).
Now my question is why? Is there a reason why Prolog only "accepts" full lines ended with a period when reading from a pipe (actually reading from any stream you may want to read)? And why does read
block while wait_for_input/3
doesn't (assuming the message is not flushed)?
Thanks!