Linux inter-process communication-famous pipelines (FIFO) and linuxfifo
Famous pipe (FIFO)
Named Pipes are also called FIFO files, which are special files. Since all linux objects can be regarded as files, the use of Named Pipes becomes very consistent with file operations.
(1) create a named pipe
You can use one of the following two functions to create named pipelines.
#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 indicates the file name, while mode indicates the read and write permissions of the specified file. Mknod is an old function, and the mkfifo function is simpler and more standard. Therefore, mkfifo is recommended.
open(const char *path, O_RDONLY);//1open(const char *path, O_RDONLY | O_NONBLOCK);//2open(const char *path, O_WRONLY);//3open(const char *path, O_WRONLY | O_NONBLOCK);//4
(2) Open the Named Pipe
Like opening other files, you can use open. There are usually four methods:
Note the following two points:
1. A program cannot open a FIFO file in O_RDWR (read/write) mode for read/write operations, but its behavior is not clearly defined, because, for example, a pipeline is opened in read/write mode, the process will read its own output, and we usually use FIFO only for one-way data transmission.
2. The first-in-first-out path name is passed to open, rather than a normal file. (For example, const char * export o_name = "/tmp/my_fifo ";)
3. The option O_NONBLOCK In the second parameter. The option O_NONBLOCK indicates non-blocking. After this option is added, the open call is non-blocking. If this option is not available, the open call is blocked.
(3) Blocking
For a FIFO file opened in read-only mode (O_RDONLY), if the open call is blocked (that is, the second parameter is O_RDONLY), unless a process opens the same FIFO file in write mode, otherwise, it will not return; if the open call is non-blocking (that is, the second parameter is O_RDONLY | O_NONBLOCK), even if no other process opens the same FIFO file in write mode, the open call succeeds and returns immediately.
For a FIFO file opened in write-only mode (O_WRONLY), if the open call is blocked (that is, the second parameter is O_WRONLY), the open call is blocked, until a process opens the same FIFO file in read-only mode. If the open call is non-blocking (that is, the second parameter is O_WRONLY | O_NONBLOCK), open always returns immediately, however, if no other process opens the same FIFO file in read-only mode,-1 will be returned for the open call and the FIFO will not be opened.
(4) use FIFO to implement inter-process communication
The write end of the MPs queue reads data from a file and then writes the data to the MPs queue. The Reading end of the MPs queue reads the data from the MPs queue and writes the data to the file.
Write code: writable owrite. 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> int main(){ const char *fifo_name = "/tmp/my_fifo"; int pipe_fd = -1; int data_fd = -1; int res = 0; const int open_mode = O_WRONLY; int bytes_sent = 0; char buffer[PIPE_BUF + 1]; int bytes_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] = '\0'; 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] = '\0'; } close(pipe_fd); close(data_fd); } else exit(EXIT_FAILURE); printf("Process %d finished\n", getpid()); exit(EXIT_SUCCESS);}
Pipeline oread. 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>int main(){ const char *fifo_name = "/tmp/my_fifo"; int pipe_fd = -1; int data_fd = -1; int res = 0; int open_mode = O_RDONLY; char buffer[PIPE_BUF + 1]; int bytes_read = 0; int bytes_write = 0; memset(buffer, '\0', 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); } else exit(EXIT_FAILURE); printf("Process %d finished, %d bytes read\n", getpid(), bytes_read); exit(EXIT_SUCCESS);}
(5) security issues of Named Pipes
One scenario is that a FIFO file contains multiple processes that write data to the same FIFO file at the same time, while only one read FIFO process reads data from the same FIFO file, data blocks are staggered. It is common for different processes to send data to a FIFO read process. The solution to this problem is to make write operations atomic. System regulations: In a FIFO opened in O_WRONLY (blocking mode), if the length of the data written is smaller than the length of the data waiting for PIPE_BUF, then or write all bytes, or do not write one byte. If all write requests are sent to a blocked FIFO, and the data length of each write request is smaller than or equal to PIPE_BUF bytes, the system will ensure that the data will not be intertwined.
A Linux inter-process communication problem
There are a lot of problems here. The main problem is that, if files are used, files are as slow as snails. Files are equivalent to storing data to the hard disk, and another program retrieves data from the hard disk, many of the computer's exquisite design is for a fast word
Communication between processes in linux
I. Pipeline (pipe)
Pipelines are the earliest IPC supported by Linux. pipelines can be divided into unknown pipelines and famous pipelines.
(1) The Nameless pipeline has the following characteristics:
1) pipelines are half-duplex and can only support one-way data flow. Two pipelines must be established when two processes need to communicate with each other;
2) an unknown pipeline is created using the pipe () function and can only be used between parent and child processes or brother processes;
3) pipelines are essentially an independent file for processes at both ends of the communication and only exist in the memory;
4) read/write operations on data: one process writes data to the pipeline, and the data written is added to the end of the pipeline buffer; the other process reads data in the buffer area of the pipeline.
(2) famous Pipelines
The famous pipeline is also half-duplex, but it allows communication between unrelated processes. Specifically, a famous Pipeline provides a path name to be associated with it and is stored in a file system in the form of FIFO (first-in-first-out. In this way, even unrelated processes can communicate with each other through FIFO, as long as they can access the provided path.
It is worth noting that writing data to the MPs queue is meaningful only when the MPs queue has a read end. Otherwise, the process that writes data to the pipeline receives the SIGPIPE signal from the kernel. The application can customize the signal processing function or directly ignore the signal.
II. Semaphores (semophore)
A semaphore is a counter that can control the synchronous access to resources by multiple threads or processes between processes. It is often implemented as a lock mechanism. Essentially, semaphores are a protected variable and can only be accessed through initialization and two standard atomic operations (P/V. (P and V Operations are also called wait (s), signal (s ))
3. Signal (Signal)
Signal is one of the oldest methods used in Unix systems for inter-process communication. The operating system sends a signal to notify a process of a scheduled event. processes that receive the signal can process the event in different ways, first, you can use the default processing mechanism-process interruption or exit. First, you can ignore the signal and customize the processing function of the signal to execute corresponding actions.
The kernel generates signals for processes to respond to different events. These events are the signal sources. The signal source can be: abnormal, other processes, terminal interruptions (Ctrl-C, Ctrl + \, etc.), job control (foreground, background process management, etc ), quota-based issues (cpu times out or files are too large), kernel notifications (such as I/O readiness), and alarms (timers ).
4. Message Queue)
A message queue is a linked list of messages. It allows one or more processes to write messages to it and one or more processes to read messages to it. In Linux, A Message Queue vector table msgque is maintained to represent all message queues in the system.
Message Queues overcome the disadvantages of low signal transmission information, and pipelines can only support unformatted byte streams and buffer limitations.
5. Shared memory)
The shared memory is mapped to a memory segment that can be accessed by other processes. The shared memory is created by a process and can be mounted to the shared memory by other processes. Shared memory is the fastest IPC Mechanism, but because linux itself cannot implement synchronous control over it, user programs need to perform concurrent access control, therefore, it generally integrates other communication mechanisms to implement inter-process communication, such as semaphores.
Socket is also a communication mechanism between processes, but its main difference with other communication methods is that it can implement process communication between different hosts.