Chapter 4 inter-process communication: Pipelines
In Chapter 11th, we learned a simple way to send messages between two processes using signals. We have created a notification event that can be used to cause a response, but the transmitted information is limited to the number of signals.
In this chapter, we will learn about pipelines, which allow exchange of more useful data between processes. At the end of this chapter, we will use our new knowledge to implement the CD database program as a very simple client/server program.
In this chapter, we will cover the following topics:
MPs queue Definition
MPs queue
MPs queue call
Parent and Child Processes
Famous pipelines: FIFO
Client/Server Method
What is an MTS queue?
We use the glossary when we connect data streams from one process to another. We usually connect the output of one process to the input of another process.
Most linu users are familiar with the idea of connecting shell commands, so that the input of one process can be directly connected to the input of another process. For shell commands, this is entered in the following method:
Cmd1 | cmd2
Shell arranges the standard input and the output of the two commands
Standard input of cmd1 to enable the keyboard
The standard output of cmd1 is connected to cmd2 as the standard input.
Connect the standard output of cmd2 to the terminal screen
In fact, shell re-connects the standard input and output streams, so that the data streams input by the keyboard can be output to the screen through two commands. Is a visual representation of this process.
In this chapter, we will learn how to achieve this effect in a program, and how to use pipelines to connect multiple processes so that we can implement a simple client/server system.
MPs queue
Perhaps the easiest way to transmit data between two programs is to use the popen and pclose functions. The two function prototypes are as follows:
# Include <stdio. h>
File * popen (const char * command, const char * open_mode );
Int pclose (File * stream_to_close );
Popen
The popen function allows one program to call another program as a new process, or send or receive data to or from it. The command string is the name of the program to run and its parameters. Open_mode must be "R" or "W ".
If open_mode is "r", the output of the called program can be used by the called program, in addition, you can use the common stdio library function to read the function from the file stream file * returned by the popen function. However, if open_mode is "W", the program can use fwrite to send data to the called program. The called program can read data from its standard input. Generally, the program being called does not know that it is reading data from another process; it simply reads its standard input stream.
The popen call must specify "R" or "W"; other options are not supported in the standard implementation of popen. This means that we cannot call another program and read and write it to it at the same time. Once a failure occurs, popen returns a null pointer. If we want to use pipelines for two-way communication, the common solution is to use two pipelines, each of which is used for one data stream.
Pclose
When the process started by popen has been completed, we can use pclose to close the file stream related to it. A pclose call is returned only when the process started by popen is completed. If the process is still running when pclose is called, The pclose call will wait for the process to end.
The pclose call usually returns the code returned by the file stream of the process that is being disabled. If a wait statement has been executed before calling pclose, the returned status will be lost, and pclose will return-1 and errno will be set to echild.
Test-read output from another program
The following is a simple example of popen and pclose, popen1.c. We will use popen in a program to access the information output by uname. The uname-a command outputs system information, including the machine type, OS name, version number, and network name of the machine.
After the initialization program, we open an uname connection pipe to make it readable and set read_fp to point to the output. Finally, the pipeline directed by read_fp is closed.
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <unistd. h>
Int main ()
{
File * read_fp;
Char buffer [bufsiz + 1];
Int chars_read;
Memset (buffer, '/0', sizeof (buffer ));
Read_fp = popen ("uname-a", "R ");
If (read_fp! = NULL)
{
Chars_read = fread (buffer, sizeof (char), bufsiz, read_fp );
If (chars_read> 0)
{
Printf ("output was:-/n % s/n", buffer );
}
Pclose (read_fp );
Exit (exit_success );
}
Exit (exit_failure );
}
When we run this program, we will get the following output:
$./Popen1
Output was :-
Linux gw1 2.4.20-8 #1 Thu Mar 13 17:54:28 est 2003 i686 i686 i386 GNU/Linux
Working Principle
This program uses popen to call the uname command with the-a parameter. It then uses the returned file stream to read until the bufsiz characters are output to the screen. The uname output is captured in a program, so it can be used for processing.
Send output to popen
Now we have seen an example of capturing output from an external program. Let's take a look at sending output to another program. This is popen2.c, which directs data to another pipeline. Here we will use OD (octal dump ).
Test-send output to external programs
Let's look at the code below. If you want to, you can input it into the text editor.
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <unistd. h>
Int main ()
{
File * write_fp;
Char buffer [bufsiz + 1];
Sprintf (buffer, "Once upon a time, there was.../N ");
Write_fp = popen ("OD-c", "W ");
If (write_fp! = NULL)
{
Fwrite (buffer, sizeof (char), strlen (buffer), write_fp );
Pclose (write_fp );
Exit (exit_success );
}
Exit (exit_failure );
}
When we run this program, we will get the following output:
$./Popen2
0000000 o n c e u p o n a t I m e
0000020, t h e r e w a s.../n
0000037
Working Principle
This program uses a popen with the "w" parameter to start the OD-C command, so that he can send data to this command. Then he sends a string, and the OD-C command can receive and process it. The OD-C command then outputs the processing result on its standard output.
On the command line, we can use the following command to get the same result.
$ Echo "once upon a time, there was..." | OD-C