1. Anonymous semi-Dual-pass Pipe
Main features:
A data can only be moved in one direction
B can only communicate between processes with common ancestors, that is, parent-child processes, or sibling processes.
The pipeline creation function is as follows:
# Include <unistd. h>
Int pipe (int fd [2]);
Int FD [2] is an array of file descriptors with a length of 2. FD [0] indicates the Reading end, and FD [1] indicates the writing end. If 0 is returned, the operation is successful. If-1 is returned, the operation fails.
2. Parent-Child process pipeline Communication
Call pipe first and then fork. Because the child process automatically inherits the data segment of the parent process, the Parent and Child processes have the operation right of the pipeline at the same time. The specific output depends on the input and output.
// Fath_chill.c
# Include <unistd. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <fcntl. h>
# Include <sys/types. h>
# Include <limits. h>
# Define bufsz pipe_buf // The default one-time read/write data length of the pipe_buf Pipe
Int main (void)
{
Int FD [2];
Char Buf [bufsz];
Pid_t PID;
Int Len;
If (pipe (FD) <0) {// create an MPS queue
Perror ("failed to pipe ");
Exit (1 );
}
If (pid = fork () <0 ){
Perror ("failed to fork ");
Exit (1 );
}
Else if (pid> 0 ){
Close (FD [0]); // The parent process closes the read end of the Pipeline
Write (FD [1], "Hello my son! /N ", 14); // write data
Exit (0 );
}
Else {
Close (FD [1]); // sub-process closes the write end of the Pipeline
Len = read (FD [0], Buf, bufsz); // read data
If (LEN <0 ){
Perror ("process failed when read a pipe ");
Exit (1 );
}
Else
Write (stdout_fileno, Buf, Len );
Exit (0 );
}
}
Result:
./Fath_chill
Hello my son!
3. Pipe communication between sibling Processes
When using a pipeline between sibling processes, you should first create an pipeline in the parent process, then call fork to create a child process, and jointly maintain the pipeline direction in the parent and child processes.
// Bro_bro.c
# Include <unistd. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <fcntl. h>
# Include <sys/types. h>
# Include <limits. h>
# Define bufsz pipe_buf
Void err_quit (char * MSG ){
Perror (MSG );
Exit (1 );
}
Int main (void)
{
Int FD [2];
Char Buf [bufsz];
Pid_t PID;
Int Len;
If (pipe (FD) <0) // create an MPS queue
Err_quit ("pipe ");
If (pid = fork () <0) // create the first child process
Err_quit ("fork ");
Else if (pid = 0) {// The first child process
Close (FD [0]); // The first one is to write, so close the Reading end
Write (FD [1], "Hello Brother! ", 14 );
Exit (0 );
}
If (pid = fork () <0) // create the second sub-process
Err_quit ("fork ");
Else if (pid> 0) {// The parent process does not read or write the pipeline, so both ends are closed.
Close (FD [0]);
Close (FD [1]);
Exit (0 );
}
Else {// second sub-process
Close (FD [1]); // close the write end because it is intended to be read.
Len = read (FD [0], Buf, bufsz );
Write (stdout_fileno, Buf, Len );
Exit (0 );
}
}
Result:
./Bro_bro
Hello brother!
When creating the first child process, the parent process does not close both ends of the MPs queue, but closes the MPs queue only when the second process is created, child processes can inherit the surviving pipeline, rather than a pipeline that has been closed at both ends.
4. Standard Functions for creating Pipelines
# Include <stdio. h>
File * popen (const char * command, const char * mode );
Int pclose (File * stream );
Command is a pointer to a command string that can be executed in shell. The mode parameter can only be r or W, indicating whether the return value of the popen function is a Read File pointer or a Write File pointer.
If the function fails, null or even errno is returned.
The popen function first creates a pipeline, then calls the fork function to create a sub-process, then executes an exec function call, executes the command, and then returns a standard I/O file pointer. Disable pclose.
# Include <unistd. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <fcntl. h>
# Include <limits. h>
# Define bufsz pipe_buf
Int main ()
{
File * FP;
Char * cmd = "cat file1 ";
Cha * Buf [bufsz];
If (FP = popen (CMD, "R") = NULL ){
Perror ("fail to popen ");
Exit (1 );
}
While (fgets (BUF, bufsz, FP )! = NULL)
Printf ("% s", Buf );
Pclose (FP );
Exit (0 );
}