Famous Pipes (FIFO)
Named Pipes are also known as FIFO files and are a special kind of file. Because everything in Linux can be treated as a file, the use of named pipes has become very uniform with file operations.
(1) Creating a named pipe
You can create a named pipe with one of the following two functions.
#include <sys/types.h> #include <sys/stat.h>int Mkfifo (const char *filename, mode_t mode); int Mknod (const char *filename, mode_t mode | S_ififo, (dev_t) 0 );
Filname refers to the file name, and mode is the read and write permission for the specified files. Mknod is a relatively old function, and using the Mkfifo function is simpler and more prescriptive, so it is recommended to use mkfifo.
Open (constchar *path, o_rdonly); // 1Open (constchar *path, o_rdonly | O_nonblock); // 2Open (constchar *path, o_wronly); // 3Open (constchar *path, o_wronly | O_nonblock); // 4
(2) opening a named pipe
Like opening other files, you can open it with open . There are usually four ways to do this:
There are two points to note:
1, is the program cannot open the FIFO file in o_rdwr( read-write ) mode to read and write operations, and its behavior is not clearly defined, because such as a pipe to read / When the write is opened, the process reads back its output, and we usually use FIFO only for one-way data transfer.
2, is passed to the open call is the FIFO path name, but not the normal file. (such as: const char *fifo_name = "/tmp/my_fifo"; )
3, the second parameter in the option o_nonblock, the option O_nonblock represents non-blocking, plus this option, indicates that the open call is non-blocking, if there is no option, it means Open the call is blocked.
(3) blocking problems
o_rdonly ) Open the fifo file, if open The call is blocked (that is, the second argument is o_rdonly fifo open o_rdonly | o_nonblock fifo file, open The call succeeds and returns immediately.
For write-only mode (o_wronly) Open theFIFOfile, ifOpenthe call is blocked (that is, the second argument is ao_wronly),OpenThe call will be blocked until a process has opened the same read-only modeFIFOfile, ifOpenThe call is non-blocking (that is, the second argument is aO_wronly | O_nonblock),Openalways returns immediately, but if no other process opens the same read-only modeFIFOfiles,OpenCall will return-1, andFIFOwill not be opened.
(4) Use FIFO for interprocess communication
The write end of the pipeline reads the data from a file and writes to the write pipeline. The read end of the pipeline is read from the pipeline and written to the file.
Write-side code:fifowrite.c
#include <unistd.h>#include<stdlib.h>#include<fcntl.h>#include<limits.h>#include<sys/types.h>#include<sys/stat.h>#include<stdio.h>#include<string.h>intMain () {Const Char*fifo_name ="/tmp/my_fifo"; intPIPE_FD =-1; intDATA_FD =-1; intres =0; Const intOpen_mode =o_wronly; intBytes_sent =0; CharBuffer[pipe_buf +1]; intBytes_read =0; if(Access (fifo_name, F_OK) = =-1) {printf ("Create the FIFO pipe.\n"); Res= Mkfifo (Fifo_name,0777); if(Res! =0) {fprintf (stderr,"Could not create FIFO%s\n", Fifo_name); Exit (Exit_failure); }} printf ("Process%d opening FIFO o_wronly\n", Getpid ()); PIPE_FD=Open (Fifo_name, open_mode); printf ("Process%d result%d\n", Getpid (), PIPE_FD); if(PIPE_FD! =-1) {Bytes_read=0; DATA_FD= Open ("Data.txt", o_rdonly); if(DATA_FD = =-1) {close (PIPE_FD); fprintf (stderr,"Open File[data.txt] failed\n"); return-1; } bytes_read=Read (data_fd, buffer, pipe_buf); Buffer[bytes_read]=' /'; while(Bytes_read >0) {res=Write (pipe_fd, buffer, bytes_read); if(res = =-1) {fprintf (stderr,"Write error on pipe\n"); Exit (Exit_failure); } bytes_sent+=Res; Bytes_read=Read (data_fd, buffer, pipe_buf); Buffer[bytes_read]=' /'; } close (PIPE_FD); Close (DATA_FD); } Elseexit (exit_failure); printf ("Process%d finished\n", Getpid ()); Exit (exit_success);}
Pipe Read end: fiforead.c
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>#include<limits.h>#include<string.h>intMain () {Const Char*fifo_name ="/tmp/my_fifo"; intPIPE_FD =-1; intDATA_FD =-1; intres =0; intOpen_mode =o_rdonly; CharBuffer[pipe_buf +1]; intBytes_read =0; intBytes_write =0; memset (Buffer,' /',sizeof(buffer)); printf ("Process%d opening FIFO o_rdonly\n", Getpid ()); PIPE_FD=Open (Fifo_name, open_mode); DATA_FD= Open ("DataFormFIFO.txt", o_wronly| O_creat,0644); if(DATA_FD = =-1) {fprintf (stderr,"Open File[dataformfifo.txt] failed\n"); Close (PIPE_FD); return-1; } printf ("Process%d result%d\n", Getpid (), PIPE_FD); if(PIPE_FD! =-1) { Do{res=Read (pipe_fd, buffer, pipe_buf); Bytes_write=Write (data_fd, buffer, res); Bytes_read+=Res; } while(Res >0); Close (PIPE_FD); Close (DATA_FD); } Elseexit (exit_failure); printf ("Process%d finished,%d bytes read\n", Getpid (), bytes_read); Exit (exit_success);}
(5) Security issues with Named pipes
One situation is that aFIFOfile, there are multiple processes simultaneously to the sameFIFOfiles write data, and only one readFIFOprocess in the sameFIFOwhen reading data in a file, the data blocks are interleaved with each other。 Different processes to aFIFOThe read process sends the data in a very common situation. ItThe solution to the problem is to make the writing Operation Atomic. The system stipulates that: in ao_wronly(that is, blocking mode) Open theFIFOif the length of the written data is less than the waitPipe_buf, either all bytes are written, or none of the bytes are written. If all of the write requests are destined for a blockedFIFO, and the data length of each write request is less than or equal toPipe_bufbytes, the system ensures that the data will never be interleaved.
Linux interprocess communication-known pipeline (FIFO)