Advanced Programming for UNIX Environments (16) interprocess communication

Source: Internet
Author: User
Tags message queue semaphore stdin

interprocess communication (IPC) refers to a mechanism for exchanging data between two processes. The modern OS has a protection mechanism for the process, so two processes cannot exchange data directly and must be done through a mechanism.
The role of the IPC mechanism:
(1) A software can also be more easily integrated with third-party software or cores, or ported. Like pipelines, execute ps–aux under the Shell | grep bash.
(2) Simplify the software structure, you can divide a software into multiple processes or threads, and work together through the IPC. such as Message Queuing.
(3) Let the operating system each module Exchange data, including kernel and application mechanism.
(4) Provide multi-threaded synchronization mechanisms between processes or the same process, such as semaphores.

1. Pipeline

The pipe is half-duplex, the data can only flow in one direction; When communication is required, two pipelines are required to be used only for parent-child processes or sibling processes (kinship processes) to form separate file systems: Pipelines are a single file for processes at both ends of a pipeline, but it is not an ordinary file. It does not belong to a file system, but to itself, constitutes a file system, and only exists in memory.

Read and write data: a process that writes to the pipeline is read out by the process at the other end of the pipeline. The content that is written is added to the end of the pipe buffer every time, and the data is read from the head of the buffer each time.
Pipeline creation: int pipe (int fd[2]);
The pipeline reads and writes: The pipeline file is also a kind of file, uses Write,read can complete reads and writes. The two ends of the pipe can be described by the description character Fd[0] and fd[1], and it is important to note that the ends of the pipe are fixed on the task. That is, one end can only be used for reading, represented by the description word fd[0], which is called the pipe reading end, and the other end can only be used for writing, by the description word fd[1] to be said to be the pipe write end. If you attempt to read data from the pipe write end, or write data to the pipe read end, it will cause an error to occur.
Pipe shutdown: The pipe file is also a file, so close it with close.
 Pipeline limitations: (1) Only one-way data flow is supported, (2) can only be used between processes with affinity, (3) No Name, (4) The buffer of the pipeline is finite (piping exists in memory, a page size is allocated for the buffer when the pipeline is created), and (5) the pipeline transmits the unformatted byte stream. This requires that the reader and writer of the pipeline must agree on the format of the data beforehand, such as how many bytes count as a message (or command, or record), and so on.

Now using the pipeline to implement synchronization of the process, the parent process reads the data entered by the child process, and the child processes the recovered data from the parent process. Implements Tell_wait, Tell_parent, Tell_child, tell_parent, and Wait_child functions. The procedure is as follows:

 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5 #include <sys/types.h> 6 7 static int fd1[2],fd2[2]; 8 9 void Tell_wait () {One pipe (FD1), one pipe (FD2), and}14 void Tell_parent (pid_t pid)-{write (fd2[1], "c ", 1);}19 void wait_parent (void), {+ c;22 read (fd1[0],&c,1), if (c!= ' P ') F ("wait_parent:incorretc data"); exit (0),}28 else29 printf ("Read from parent.\n"),}31 Void Tell_child (pid_t pid), (Fd1[1], "P", 1),}35 void Wait_child () $ {PNS char c;38 read (fd2[0],&c,1)         (c!= ' C '), ("Wait_child:incorretc Data"), (0);}44 else45  printf ("Read from child.\n"),}47 int main () (), pid_t pid;51 tell_wait (), pid =fork (), if (PID = =-1) perror ("fork () Error"),}58 exit ( -1), or if (PID = = 0) ("Child process exec.\n"), Wait_parent (), Tell_parent (Getppid ()); 63}64 Else65 {("Parent process exec.\n"), Tell_child (PID), Wait_child (); 69 70} + exit (0); 72}

The results of the program execution are as follows:

Popen and Pclose functions

A common operation is to create a pipe to connect to another process, and then read its output or send data to its input. The Popen and Pcolse functions do this by creating a pipeline, calling fork to produce a child process, closing the unused end of the pipe, executing a shell to run the command, and then waiting for the command to terminate. The function prototypes are as follows:

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

The function Popen executes the fork first, then calls exec to execute cmdstring, and returns a standard I/O file pointer. If the type is "R", the file pointer is connected to the standard output of the cmdstring, and if the type is "W", the file pointer is connected to the standard input of the cmdstring. Popen is especially useful for constructing a simple filter program that transforms the input or output of a running command. Write a program, copy the standard input to the standard output, copy all uppercase letters to lowercase letters, the program is divided into two parts, the conversion program is as follows:

1 #include <stdio.h> 2 #include <ctype.h> 3 #include <stdlib.h> 4 int main () 5 {6     int c; 7     Whil E ((c = GetChar ())! = EOF) 8     {9         if (Isupper (c))             c= ToLower (c);         if (Putchar (c) = = EOF)             printf (" Output error "),         if (c== ' \ n ')             fflush (stdout);     }16     exit (0); 17}

Save the executable file as a change. The input and output programs are as follows:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5 #include & Lt;errno.h> 6  7 #define MAXLINE 8  9 int main () {one     char    line[maxline];12     FILE    *fpin;     if (Fpin = Popen (".//change", "r") = = NULL) [] (         "Popen () Error"), and         exit ( -1);     for (;;)     {         fputs ("prompt>", stdout),         fflush (stdout);         Maxline,fpin) = = NULL)             break;24         if (fputs (line,stdout) = = EOF) +             perror ("Fputs error to pipe "),         }28     }29     if (pclose (fpin) = =-1),     {perror (         " pclose () error ");         exit (-1); 33     }34     putchar (' \ n ');     exit (0); 36}

Program execution results are as follows

Collaborative process: When a process generates input from a filter, it also reads the output of the filter program. Popen only provides a one-way pipeline linking to the standard input or standard output of another process, and for a synergistic process, two unidirectional pipelines connected to another process, one to the standard input and one to the standard output. Write a program to show the synergy process, the program reads two integers from the standard input, the calling program calculates their and then outputs the results to standard output. The filter program is the summation program as follows:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <fcntl.h> 5 #include & Lt;unistd.h> 6 #define MAXLINE 1024x768 7  8 int main () 9 {ten     int n,int1,int2;11     char line[maxline];12     whil E ((N=read (stdin_fileno,line,maxline)) > 0) (+         line[n] = '%d%d ';         if (sscanf line, "&int1", &INT2) = = 2)             sprintf (line, "%d\n", Int1+int2),             n = strlen (line), and             if (write (stdout_ FILENO,LINE,N)! = N)             {                 perror ("Write () error");                 exit ( -1);             }24         }25         else if ( Write (Stdout_fileno, "Invalid arg\n", +)! = ()-             perror ("Write () error"),             exit ( -1);     }31     exit (0); 32}

The compilation execution is saved as an executable file for Add.

The Synergy program is as follows:

 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5 #include     <signal.h> 6 #include <string.h> 7 #define MAXLINE 1024x768 8 9 static void sig_pipe (int); int main () 12 {13     int n,fd1[2],fd2[2];14 pid_t pid;15 char line[maxline];16 if (signal (sigpipe,sig_pipe) ==sig_err) 18 {perror ("signal () error"); exit ( -1);}22 if (pipe (fd1) = = -1| |     Pipe (FD2) = = 1) perror ("pipe () error"), Exit ( -1),}27 if (PID =fork ()) = =-1) 28         {perror ("fork () Error"), Exit ( -1),}32 if (pid = = 0), {Close (fd1[1]); 35             Close (fd2[0]); if (fd1[0]! = Stdin_fileno) PNs if (dup2 (fd1[0],stdin_fileno)! = Stdin_fileno) 38              {perror ("Dup2 Error in stdin"); + Close (fd1[0]); exit (-1); 42 };43 if (fd2[1]! = Stdout_fileno) if (dup2 (fd2[1],stdout_fileno)! = Stdout_fileno) {perror ("Dup2 Error in St Dout "); Close (fd2[1]); exit ( -1),};50 if (Execl (".//add "," Add ", (c Har *) 0) = =-1) {perror ("execl () error"); exit ( -1);}55}56 else5 7 {fd1[0]; Fd2[1 ("Enter Number:"), and (Fgets (LI);             Ne,maxline,stdin) = NULL) (strlen) (line), if (Write (fd1[1],line,n)! = N) 65 {perror ("Write Errot to Pipe"); ( -1);}69 if (n= Read (Fd2[0],line,maxline)) ==-1) {perror ("read error to Pipe"); (-1                 );}74 if (n== 0) ("Child Close pipe.\n"); 77            break;78 }79 Line[n] = ' n '; printf ("The result is:"); fputs (line,stdout); 82}83 }84}85 sig_pipe (int signo) ("Sigpipe caught\n"); (1); 90}

The results of the program execution are as follows:

2. FIFO

A FIFO differs from a pipe in that it provides a path name associated with it, which exists in the file system as a FIFO file. Thus, even processes that do not have affinity to the FIFO creation process can communicate with each other through the FIFO as long as the path is accessible. FIFO strictly follows the first in and out, and the pipes and FIFO reads always return data from the beginning, and their writes add data to the end. They do not support file location operations such as Lseek ().

Named pipes for Named Pipes are created: int mkfifo (const char * pathname, mode_t mode).
Named pipes open: Named pipes have a more open operation than pipes: open, when open, uses the O_NONBLOCK flag to denote non-blocking mode, such as Fd=open ("/tmp/fifo", o_rdonly| o_nonblock,0).
Read-in of Named pipes: Read reads the pipeline data, reads into blocking and non-blocking modes, blocking mode, and if no data is entered, the process stops at read. Until new data is written, or the pipeline is closed, it will continue.
Write to Named Pipes: Write writes to the pipe data, pipe_buf represents the maximum length of time that the pipe read operation is triggered. If the data is written longer than Pipe_buf, write will trigger the read operation multiple times.
Shutdown of Named pipes: The pipe file is also a file, so close it with close.

Two Uses of FIFO:

(1) FIFO has a shell command to use to transfer data from one pipe line to another, eliminating the need to create intermediate temporary files.

(2) FIFO is used in the client process-server process application to pass data between the client process and the server process.

3. XSI IPC

Message Queuing, semaphores, shared storage similar characteristics are as follows: with identifiers and keys, identifiers are internal names of IPC objects, each IPC object is associated with a key, creating an IPC structure requires specifying a key with a data type of key_t. The permission structure is set for each IPC.

Pros and Cons: The IPC structure is functional in the system-wide, with no access count. There are no names in the file system, no file descriptors, and no multiplexing I/O functions for them. Advantages: Reliable, flow is controlled, record-oriented, can be processed in a non-FIFO way.

Message Queuing (Messge queue): Message Queuing is a linked table of messages, including POSIX Message Queuing SYSTEMV Message Queuing.  It overcomes the shortcoming of limited amount of information in the first two modes of communication, the process with Write permission can add new message to message queue according to certain rules, and the process with Read permission to message queue can read the message from Message queue.  Semaphore (Semaphore): primarily as a means of synchronization and mutual exclusion between processes and between different threads of the same process. Shared memory: This can be said to be the most useful way to communicate between processes. It allows multiple processes to access the same piece of memory space, and different processes can see the update of the data in the shared memory in a timely manner. This kind of communication needs to rely on some kind of synchronization mechanism, such as mutual exclusion lock and semaphore. Recommendation: To learn to use pipelines and FIFO, because these two techniques can still be used effectively in a large number of applications, in new applications, to avoid using Message Queuing and semaphores as much as possible, you should consider full-duplex piping and record locks.

Advanced Programming for UNIX Environments (16) interprocess communication

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.