Pipeline, an ancient form of inter-process communication. A pipeline is created by a process, and then the process calls fork, and then the parent and child processes can communicate with the pipeline.
Function Prototypes:
#include <unistd.h>int pipe (int filedes[2]); Successfully returned 0, error returned-1
The parameter filedes returns two file descriptors. FILEDES[0] used for input, filedes[1] for output. Note that, after experimentation, the two descriptors here do not correspond to standard input and standard output. The following is a simple test routine:
#include <stdio.h> #include <unistd.h> #define MAXLINE 1024x768 int main (void) { int n; int fd[2]; pid_t pid; Char Buf[maxline]; if (pipe (FD) < 0) return-1; if (PID = fork ()) < 0) return-1; else if (PID > 0) { //parent Process printf ("Parent ID =%d\n", Getpid ()); Close (fd[0]); Write (fd[1], "Hello world\n", (); } else { //Sub-process printf ("Child ID =%d\n", Getpid ()); Close (fd[1]); n = Read (fd[0], buf, MAXLINE); Write (Stdout_fileno, buf, n); } return 0;}
Operation Result:
The above program utilizes pipelines to enable data to be passed from the parent process to the child process. The direction in which the data is passed determines which descriptors each process should close.
Now let's look at how to use the pipeline in a shell command:
The pipe Command "|" was used. The output of the previous command is used as input to the latter command. Note that the output here can only be standard output, the input can only be standard input, that is, the previous command must have the ability to output to the standard output, the latter command must have the ability to accept the standard input. The website from bird brother.
The following is a program that simulates the behavior of the above shell commands. A common operation is to create a pipe to connect to another process, and then read its output or send data to its input. This is possible with the following two library functions:
#include <stdio.h>file *popen (const char *cmdstring, const char *type); Successful return of file pointer, error returned nullint pclose (file *fp); Get cmdstring termination status, error return-1
Popen is equivalent to fork, exec ("cmdstring") to start a child process. The meaning of type is as follows:
- "R" means that the file pointer is connected to the standard output of cmdstring, and the parent process reads the cmdstring data.
- "W" means that the file pointer is connected to the standard input of cmdstring, and the parent process writes data to cmdstring.
There are several issues to note:
- The file pointer returned by Popen also does not correspond to standard input and standard output, which can be viewed using the Fileno function to convert the file pointer to a file descriptor.
- The function pclose not only shuts down the standard I/O stream, but also gets the child process termination state. If you do not use this function, when the parent process is still running and the child process finishes running, a zombie process will be generated, which will be explained by experiments.
The test routines are as follows:
#include <stdio.h> #include <unistd.h> #include <string.h> #define MAXLINE 1024x768 int main (void) { Char Buf[maxline]; FILE *fpin; int n; if (Fpin = Popen ("date", "r") = = NULL) //Start data command return-1; Fgets (buf, MAXLINE, fpin); Get output of the data command write (Stdout_fileno, buf, strlen (BUF)); Print data to Terminal Pclose (fpin); return 0;}
Operation Result:
The parent process test correctly received the output of the data command, and the pipeline was successfully transferred. If you remove Pclose (fpin), this statement, the result is as follows:
Ah oh, there is a zombie process. This is caused by the parent process not getting the terminating state of the child process.
Reference: Advanced programming for the UNIX environment p397-p404.