1. Overview
The MPs queue has no name. It is applicable to kinship-related processes.
FIFO refers to first in first out, which has a path name associated with it, so that it can be used between unrelated processes. It is also called named pipe.
Both of them are unidirectional data streams (half-duplex pipelines), with the continuity of processes, data is both first-in-first-out, and communication between processes does not require some form of synchronization.
2. MPS queue
# Include <unistd. h>
Int pipe (int fd [2]);
Return Value: Success 0, error-1;
Returns two file descriptors: FD [0] for open reading, and FD [1] for open writing.
Typical use:
(1) unidirectional
Provides communication between parent and child processes.
The parent process creates an MPS queue and fork generates its own copy.
The parent process closes the read end and is used to write data to the MPs queue.
The sub-process closes the write end for reading from the pipeline.
(2) bidirectional
Pipe (pipe1 [2]); pipe1 [0], pipe1 [1]
Pipe (pipe2 [2]); pipe2 [0], pipe2 [1]
Fork () = 0 {// sub-process
Close (pipe1 [1]);
Close (pipe2 [0]);
}
// Parent process
Close (pipe1 [0]);
Close (pipe2 [1]);
3. Pipe example
The following describes a client-server program.
The customer sends the path name, and the server sends the file content to the customer.
# Include "unp. H "Void client (INT, INT), server (INT, INT); int main (void) {int pipe1 [2], pipe2 [2]; // create two pipelines // it will also be created in the sub-process
Pipe (pipe1); pipe (pipe2); int childid = fork (); If (childid = 0) {// child close (pipe1 [1]); // close write (pipe2 [0]); // close read server (pipe1 [0], pipe2 [1]); exit (0 );} close (pipe1 [0]); close (pipe2 [1]); client (pipe2 [0], pipe1 [1]); // wait for the child process to terminate waitpid (childid, null, 0); exit (0 );}
Server. C code:
# Include "unp. H "// read the file name from the pipeline // send the file to the client void server (INT readfd, int writefd) {char buff [maxline + 1] through the pipeline; ssize_t n = read (readfd, buff, maxline); If (n = 0) {err_quit ("end-of-file while reading pathname ");} buff [N] = '\ 0'; int FD = open (buff, o_rdonly); If (FD <0) {snprintf (buff + N, sizeof (buff)-N, ": Can't open, % s \ n", strerror (errno); n = strlen (buff); write (writefd, buff, n );} else {While (n = read (FD, buff, maxline)> 0) {write (writefd, buff, n) ;}close (FD );}}
Client. C source code:
# Include "unp. H "// read the file path name from the standard input, // send it to the server through the pipeline, // write the content of the file received from the pipeline to the standard output void client (INT readfd, int writefd) {char buff [maxline]; fgets (buff, maxline, stdin); size_t Len = strlen (buff); If (buff [Len-1] = '\ n ') {-- Len;} write (writefd, buff, Len); ssize_t N; while (n = read (readfd, buff, maxline)> 0) {write (stdout_fileno, buff, n );}}
4. FIFO
The maximum difference between a media transcoding queue and a media transcoding queue is that it has a name and is applicable to unrelated processes.
# Include <sys/types. h>
# Include <sys/STAT. h>
Int mkfifo (const char * pathname, mode_t mode );
Mkfilo implicitly specifies o_creat | o_excl. If the path already exists, eexist is returned.
If you do not want to create a new FIFO, you can call open.
Mode is similar to the second parameter of open. By default, file_mode (s_irusr | s_iwusr | s_irgrp | s_iroth) is defined ).
5. unrelated customers and servers
That is, the file name sent by the client above. The method used by the server to read the file content from the client in two independent processes.
Server Source Code:
# Include "unp. H "Void server (INT, INT); // The server creates two named pipelines. // open is used for reading on one and open is used for writing int main (void) on the other) {// default o_creat | o_excl // check whether the path already exists, that is, eexist if (mkfifo ("/tmp/fifo.1", file_mode) & (errno! = Eexist) {err_sys ("can't create/tmp/mongoo.1");} If (mkfifo ("/tmp/mongoo.2", file_mode) & (errno! = Eexist) {// Delete the path from the file system, that is, the first-in-first-out name // The File Link count minus 1, // when the value is 0, when no process is using a file, delete the file unlink ("tmp/cmdo.1"); err_sys ("can't create/tmp/cmdo.2 ");} int readfd = open ("/tmp/mongoo.1", o_rdonly, 0); int writefd = open ("/tmp/mongoo.2", o_wronly, 0); server (readfd, writefd); exit (0 );}
Client source code:
# Include "unp. H "Void client (INT, INT); // open the pipeline already created on the server, // One for reading and one for writing, opposite to the int main (void) on the server) {int writefd = open ("/tmp/mongoo.1", o_wronly, 0); int readfd = open ("/tmp/mongoo.2", o_rdonly, 0); client (readfd, writefd); close (readfd); close (writefd); // The unlink ("/tmp/logs O.1") of the MPs queue deleted by the client; unlink ("/tmp/logs O.2 "); exit (0 );}
For more information about server. C and client. C, see the preceding section.
Note:
Note the open sequence when using FIFO.
If no process opens the FIFO to write, the process that opens the FIFO to read will be blocked.
Therefore, when enabling FIFO, you must read and write data on one instance. You cannot enable read and write data at the same time.
That is, open (read); open (write );
Open (read); open (write );
It will cause deadlocks and block reading.
6. Extra pipe and FIFO attributes
See unpv2 P44, section 4.7.
7. Some Features
(1) write to the FIFO is an atomic operation, which can be viewed as a whole.
(2) FIFO can only be used on a single host in the IPC format. It cannot be used in nfs-installed file systems.
(3) the pipeline is a byte stream and the system does not explain it.