Linux interprocess communication-----Pipeline Summary Example __linux

Source: Internet
Author: User
Tags stdin
main content: Anonymous pipe, command pipeline. (Pipe, Popen, Mkfifo functions)


Pipe Introduction:

Pipelines are a way of communicating between processes, which is equivalent to having a tunnel between two processes that can pass the message through the tunnel; The pipe is located outside the address space of the process, and the pipe is divided into anonymous pipes and named pipes two kinds;
anonymous pipes are created by pipe, and named Pipes are created by Mkfifo;

#include <unistd.h>
int pipe (int pipefd[2]);

Returns two descriptors: Pipefd[0] is the read end of the pipe, pipefd[1] is the writing end of the pipe;


The following is an instance of a parent-child process using pipe communication: The main function creates two pipes and generates a subprocess with fork, which runs as a parent, and the server runs as a child process. The first pipe is used to send the pathname from the client to the server, and the second pipeline is used to send the contents of the file from the server to the client.
Client Write pipe1[1]-----pipe1[0] Server Read
Server Write pipe2[1]-----pipe2[0] Client Read

/************************************************************************* > File name:mainpipe.c > Author: &G T Mail: > Created time:2016 year April 20 Wednesday 22:25 15 seconds ****************************************************************** /* * Main function creates two pipes and generates a child process with fork * The client runs as a parent, and the server runs as a subprocess * The first pipe is used to send the pathname from the client to the server * The second pipeline is used to send the file from the server to the client * CIN --Client Write pipe1[1]-----pipe1[0] Server Read * server write pipe2[1]-----pipe2[0] Client Read * * * #include <stdio.h> #include <unistd.h&gt
; #include <sys/types.h> #include <sys/wait.h> #include <string.h> #include <sys/stat.h> #
    Include <fcntl.h>//the server reads the name of the file from the RfD and writes the contents of the file to the WFD void server (int rfd, int wfd) {char filename[1024];

    Char filecontent[2048];
    memset (fileName, 0, 1024);

    memset (filecontent, 0, 2048);
    Read the name of the file from the rfd, int n = Read (RFD, fileName, 1024);
    Filename[n] = 0;

    printf ("Server receive the file name is%s\n", fileName); int filefd = open (FileName, o_rdonly);//Open TextPieces if (FILEFD < 0) {printf ("open error\n");
    Return
         else{//reads the contents of the file and writes it to the WFD//reads the contents of the file into filecontent int num = 0; while (num = Read (FILEFD, filecontent, 2048)) > 0} {printf ("server Read the Filecontent is:%s", Fileconten
            T);
        Writes the contents of the filecontent to the WFD write (WFD, filecontent, num);
    } close (FILEFD);
    Close (RFD);

Close (WFD);
    }//Client reads the contents of the file from the RfD and writes the file to WFD in the name void client (int rfd, int wfd) {char filename[1024];

    Char filecontent[2048];
    memset (fileName, 0, 1024);
    
    memset (filecontent, 0, 2048);
    printf ("Input file name:");

    The name of the input file from the standard input fgets (fileName, 1024, stdin);
    int len = strlen (fileName);

    if (filename[len-1] = = ' \ n ') len--;
    Write the name of the file to the WFD (WFD, FileName, Len);
    printf ("filename =%s\n", filename);
    Reads the contents of the file from the RfD int n; while ((n = Read (RFD, filecontent, 2048)) > 0) {printf ("Client receive thE content is:%s ", filecontent);
    Close (RFD);
Close (WFD);
    }//main function int main () {//Create two pipes.

    int pipe1[2], pipe2[2];
    int ret = pipe (PIPE1);
        if (Ret < 0) {printf ("pipe error\n");
    return-1;
    RET = pipe (PIPE2);
        if (Ret < 0) {printf ("pipe error\n");
    return-1;    
    //Create a subprocess as a server to read the filename in pipe 1 (pipe1[0]) and output the contents of the file to the pipe2[1 of pipeline 2 pid_t child_pid = fork ();
        if (Child_pid < 0) {printf ("fork error\n");
    return-1;
        else if (Child_pid > 0) {//parent process//shutdown Pipe 1 Write, close pipe 2 read, pipe1[1], pipe2[0] Close (pipe1[1);

        Close (pipe2[0]);
    Server (Pipe1[0], pipe2[1]);
        else if (Child_pid = = 0) {//subprocess/Shut down pipe 1 read, close pipe 2 write, pipe1[0], pipe2[1] Close (pipe1[0);
        Close (pipe2[1]);
    Client (Pipe2[0], pipe1[1]);
} waitpid (Child_pid, NULL, 0);/wait child process exit return 0;
 }

The results of the operation are:

root@linux_ever:~/linux_ever/process_thread/ch4#./mainpipe 
Input file name:./data
filename =./data
Server Receive the file name is./data

Server Read the filecontent is:file content linuxever
client receive the content Is:file content Linuxever

known pipes (also known as FIFO):A well-known pipe is created with the Mkfifo function.

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo (const char *pathname, mode_t mode)
Create named pipe successfully returned 0; parameter is a pathname is the name of the FIFO pipeline file created; Mode user right is the identity bit, for example, 0644;
Once you have created a pipe file, you need to open the file when you want to communicate with it and other processes.

open rule for Named Pipes if the current open operation is open FIFO for reading
1:o_nonblock disable: block until a corresponding process opens the FIFO for writing
2:o_nonblock enable: Immediately return to success
If the current open operation is open FIFO for write
1:o_nonblock disable: block until a corresponding process opens the FIFO for reading
2:o_nonblock enable: Immediately return failure, error code is ENXIO

OUTFD = open ("Fifop", O_wronly | O_nonblock);/Not blocking write
OUTFD = open ("Fifop", o_wronly); Blocking mode

For example:
1: A process opens the named pipe write, which is blocked by default, and if the pipe does not have another process open for reading, the process blocks on write until there is a process read open;
2: A process opens the named pipe read, which is blocked by default, and if the pipe does not have another process open to write, the process blocks on read until there is a process write open;
Usually open in blocking mode, if it is open in non-blocking mode, every time from the file to read data will return immediately, even if there is no data;
Named pipes and anonymous pipes difference: 1: One limitation of pipeline applications is that only communication between processes that have a common ancestor (a kinship).
2: If we want to exchange data between unrelated processes, you can use a FIFO file to do this work, which is often referred to as a named pipe.

3: Named pipe is a special type of file;


pipelines can pass data between parent-child processes

Pipelines can pass data between parent-child processes, taking advantage of the fact that two pipe file descriptors pipefd[0] and pipefd[1 are open after the fork call. This enables the parent process to pass data to the child process through pipelines, or the child process passes the data to the parent process through a pipe.

If you want to transfer data in both directions, you can create two pipes. You can also create a full-duplex pipe by Socketpair.



Example 1: The parent process communicates through anonymous and child processes, the parent process writes data to the anonymous pipe, and the subprocess reads the data from the anonymous pipe and outputs it to the standard output

/************************************************************************* > File Name:pipe1.cpp > Author: " ; Mail: > Created time:2015 year December 20 Sunday 19:48 57 seconds ****************************************************************** /#include <iostream> #include <unistd.h> #include <cstdlib> #include <fcntl.h> #include &

lt;string> #include <sys/wait.h> #include <string.h> using namespace std;
    /* 1: The parent process creates a pipeline, 0-read, 1-write 2: The parent process creates a subprocess 3: Let the parent process write information to the pipeline, the subprocess reads the information from the pipe, and writes the message from the standard input to the pipe 4: The child process outputs the read information to the standard output/int main () {
    int pipefd[2];
    Char buff[1024];

    memset (buff, 0, 1024);
    int ret = pipe (PIPEFD);
        if (ret!= 0) {cerr << "pipe error ..." << Endl; 
    Exit (-1);
    pid_t pid = fork ();
        if (PID < 0) {cerr << "fork error ..." << Endl;
    Exit (-1);
        else if (PID = = 0) {//Close the write end of the pipe (pipefd[1]);
        int ret = 0; cout << "TThe ' child process ... ' << Endl;
            while (1) {ret = read (pipefd[0], (void *) buff, 1024);
                if (ret = 0) {cout << "end of Read ..." << Endl;
            Exit (0); 
            } cout << "child read:";
            cout << buff << Endl;
        memset (buff, 0, 1024);
    Close (pipefd[0]);
        else if (PID > 0) {close (pipefd[0]);
        cout << "This is parent process ..." << Endl;
            while (Cin.getline (buff, 1024)) {cout << "parent write:";

            cout << buff << Endl;
            Write (pipefd[1], buff, 1024);
        memset (buff, 0, 1024);
        Close (pipefd[1]);
    Wait (NULL);
} exit (0);
 }


Example 2: Using a named pipe instance

Process 1 Creates a named pipe Myfifo and writes it open in blocking mode, and process 1 obtains data from standard input and writes to the named pipe;
Process 2 read in a blocking way open the named pipe file Myfifo, process 2 reads the data from the named pipe and outputs it to the standard output;

Process 1:write_fifo.cpp

/************************************************************************* > File Name:write_fifo.cpp > Author: > Mail: > Created time:2015 year December 20 Sunday 20:53 29 seconds ***************************************************** /#include <iostream> #include <sys/types.h> #include <sys/stat.h> #include <

cstdlib> #include <fcntl.h> #include <string.h> #include <unistd.h> using namespace std;
    /* 1: Create named pipe 2: from standard input to buffer 3: Open named pipe, write contents of buffer into named pipe/int main () {int ret = MKFIFO ("Myfifo", 0666);
        if (Ret < 0) {cerr << "Mkfifo error ..." << Endl;
    Exit (-1);
    } Char buff[1024];
    memset (buff, 0, 1024);
    int wrfd;
    cout << "wating for another process open the Myfifo to Reading ..." << Endl;
    WRFD = open ("Myfifo", o_wronly);
        if (wrfd = = 1) {cerr << "open error ..." << Endl;
    Exit (-1);
    pid_t pid = Getpid (); cout<< "Process" << pid << "write:";
        while (Cin.getline (buff, 1024)) {write (WRFD, buff, strlen (buff));
        memset (buff, 0, 1024);
    cout << "process" << pid << "write:";
    Close (WRFD);
Exit (0);
 }
Process 2:read_fifo.cpp

/************************************************************************* > File Name:write_fifo.cpp > Author: > Mail: > Created time:2015 year December 20 Sunday 20:53 29 seconds ***************************************************** /#include <iostream> #include <sys/types.h> #include <sys/stat.h> #include <

cstdlib> #include <fcntl.h> #include <string.h> #include <unistd.h> using namespace std;
    /* 1: Create named pipe 2: from standard input to buffer 3: Open the named pipe, write the contents of the buffer into the named pipe/int main () {char buff[1024];
    memset (buff, 0, 1024);
    int RDFD;

    int ret = 0;
    RDFD = open ("Myfifo", o_rdonly);
        if (RDFD < 0) {cout << "open error ..." << Endl;
    Exit (-1);
    } cout << "Waiting for reading...\n";
        while (1) {ret = read (RDFD, buff, 1024);
            if (ret = 0) {cerr << "end of Read ..." << Endl;
        Break } cout << "process" << Getpid () << "read:" << buff << Endl;
    memset (buff, 0, 1024);
    Close (RDFD);
Exit (0);
 }


The Myfifo file in the following figure is the named pipe you created, and you can see that its file type is P-start;


Popen Function Introduction: The standard I/O function library provides a popen function that creates a pipe and launches another process that either reads standard input from the pipe or writes standard output to the pipe.

#include <stdio.h>

FILE *popen (const char *command, const char *type);
int Pclose (FILE *stream);

If type is r, the process that calls the function reads the standard output of the command.
If Type is w, the process that calls the function writes the standard input of the command.



Instance:

/************************************************************************* > File name:popen.c > Author: > M AIL: > Created time:2016 year April 22 Friday 21:28 40 seconds *******************************************************************
    /#include <stdio.h> #include <string.h> int main () {char buffer[1024];
    Char command[1024];
    memset (buffer, 0, 1024);

    memset (command, 0, 1024);
    Enter command printf ("Input the Command:");
    Fgets (Command, 1024, stdin);
    Remove newline symbol int n = strlen (command);

    if (command[n] = ' \ n ') {//command[n] = 0;//must be assigned a value of 0, can not be ' 0 ' command[n] = '; '/must be assigned a value of 0, or ' yes ', cannot be ' 0 '}
    Call Popen Execute command//type= ' r ', the standard output of the command is output to the pipeline, and the FP is used to draw the FILE * fp = popen (Command, "R");
        if (fp = = NULL) {printf ("Popen error\n");
    return-1;
    printf ("Output command's standard output:");
    
    The standard output of the command is read from FP while (fgets (buffer, 1024, FP)!= NULL) fputs (buffer, stdout);

    Pclose (FP); return 0;
 }

Run Result:

Standard output for output command: root@linux_ever:~/linux_ever/process_thread/ch4#./readpopen 
Input the Command:cat data
Standard output for output command: file content linuxever
root@linux_ever:~/linux_ever/process_thread/ch4#./readpopen 
Input
the standard output of the COMMAND:LS output command: Data
mainpipe
mainpipe.c
readpopen
readpopen.c
root@linux _ever:~/linux_ever/process_thread/ch4#./readpopen 
Input the command:ls-l
output command standard output: Total dosage
- rw-r--r--1 root  April 21:08 data
-rwxr-xr-x 1 root root 13377  April 22:12
mainpipe-rw-r --r--1 root  3499  April 22:12 mainpipe.c
-rwxr-xr-x 1 root root  9063 April 22:08  readpopen
  -rw-r--r--1 root  1146  April 22:08 readpopen.c

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.