Read and write simultaneously from a named pipe in C++

241 Views Asked by At

I have a process A that is writing continuously to a named pipe. It has opened it in O_NONBLOCK | O_RDWR mode. Another process B is reading continuously from that pipe. It has opened it in O_NONBLOCK | O_RDONLY mode.

Note that I am using boost::asio::posix::stream_descriptor and async_write (process A) and async_read (process B) for all this.

Now my issue is that B is not able to read from the pipe, until A stops writing. I want this to happen simultaneously. B's reading capability should only depend on whether data is present or not. It shouldn't be affected by A's writing.

How can I accomplish this?

I have tried changing the modes I have opened the file descriptors in, but to no avail. I also tried setting stream_descriptor.non_blocking(true);

Edit: I am spawning process B from process A using

system(command.c_str());

Where command holds the executable path. Also, the process is executed in the background. So I am logging to stdout when:

  1. Process A calls async_write (Before);
  2. Process A has called async_write (after);
  3. Process A async_write completion handler executes (inside it);

Similarly:

  1. Process B's, async_read is called (before);
  2. Process B's, async_read has been called (after);
  3. Process B's async_read completion handler executes (inside it).

The output I observe:
B async read calling
B async read called
A async write calling
A async write called
A async write completed
A async write calling
A async write called
A async write completed
.
.
.
<once all of A's writing is done>
B async read completed
B async read calling
B async read called
.
.
.

Edit: Thanks for letting me know about system command, but as I mentioned earlier, I am launching the command in backgroud. So what is happening is:

command = "./executable &";

The '&' symbol is causing system command to return immediately.

1

There are 1 best solutions below

2
Sam Varshavchik On

Edit: I am spawning process B from process A using

system(command.c_str());

You might be surprised to learn that system() waits for the executed command to finish before returning, and only then does this program continue running. This has nothing to do, whatsoever, with named pipes. You observe the same behavior no matter what both processes are doing: process B must finish before process A continues.

That's because, simply, that's what system does: it stops this process, executes another process, and waits for that other process to finish. If you go back and look at your textbook's description of system() you'll learn that system() returns the exit code of the spawned program. Well, to do that, you have to wait until it finishes running, doesn't it?

You can simply replace system() with fork() and exec().

system() is just nothing more than a fork(), followed by exec(), and a wait(). That call to wait() is what you got stuck on.