Process Communication
Process is the smallest unit of system allocation resources, the different processes are isolated from each other, Linux is often used for process communication in several ways
- Anonymous pipelines and well-known pipelines: Anonymous pipes are used for affinity process communication, and famous pipelines can be used between generic processes.
- Signal: A simulation of the interrupt mechanism by the software layer.
- Message Queuing
- Shared memory: Different processes share the same area of memory, and different processes can view the other's updates to shared memory in real time. Requires a synchronization mechanism, such as mutex, semaphore.
- Semaphores: Mainly used for synchronization and mutual exclusion of different processes and different threads of the same process.
- Sockets: Widely used for inter-network process communication.
Nameless Pipe
Pipelines are methods of communication based on file descriptors, and nameless pipes can only be used for process communication that is related to affinity. Create a pipeline when it creates two file descriptors, fd[0] and fd[1], where fd[0] is used to read data, fd[1] for writing data, see:
If the parent process needs to send data traffic to the child process, you can create a pipeline on the parent process, close the parent process's fd[0], and the child process's fd[1], and the child process will send it to the parent process in the opposite direction.
The following shows the parent process writing data to the pipeline from which the child process reads. The sleep () function ensures that the parent process has closed the corresponding file descriptor.
#include <stdio.h>#include<sys/types.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<unistd.h>intMainvoid) {pid_t pid; intpipe_fd[2]; Charbuf[1024x768]; Const CharData[] ="Pipeline Testing"; intReal_read, Real_write; memset (BUF,0,sizeof(BUF)); /*Creating Pipelines*/ if(Pipe (PIPE_FD) <0) {perror ("Pipe"); Exit (1); } if(PID = fork ()) <0) {perror ("Fork"); Exit (1); }Else if(PID = =0){ /*the child process closes the write descriptor and waits 1 seconds for the parent process to turn off the read descriptor*/Close (pipe_fd[1]); Sleep (2); if(Real_read = Read (pipe_fd[0], buf,1024x768)) >0) {printf ("Read pipeline content:%s\n", BUF); } Close (pipe_fd[0]); Exit (0); }Else{ /*The parent process closes the read descriptor and waits 1 seconds for the child process to close the write descriptor*/Close (pipe_fd[0]); Sleep (1); if(Real_write = Write (pipe_fd[1], data, strlen (data)) >0) {printf ("Write pipeline content:%s\n", data); } Close (pipe_fd[1]); /*Collect child process exit information*/waitpid (PID, NULL,0); Exit (0); }}
A few points to note for pipeline reading and writing
- When writing data to a pipe, the pipe read must exist, otherwise the write process will receive a sigpipe signal from the kernel.
- Writing data to the pipeline does not guarantee atomicity, and if the read process does not read the data in the pipe buffer, the write process will block.
- The parent-child process runs, and there is no guarantee of sequencing, which is simply solved with sleep ().
Standard Flow Piping
Quite a system call to create a pipeline that connects to another process, where the process refers to an executable file that can be manipulated, and the standard flow pipeline merges a series of creation processes into Popen ().
#include <stdio.h>#include<unistd.h>#include<stdlib.h>#include<fcntl.h>/*Standard pipe flow operation*/intMainvoid) {FILE*FP; Char*cmd ="Ps-ef"; Charbuf[1024x768]; /*the R file pointer connects to the command's standard output*/ if(fp = popen (cmd,"R")) ==NULL) {printf ("Popen Error"); Exit (1); } while(Fgets (BUF,1024x768, fp))! =NULL) {printf ("%s\n", BUF); } pclose (FP); Exit (0);}
Famous pipes
Linux has a dedicated special file system-pipeline files, in a FIFO file form in the file system, so that even if there is no affinity with the FIFO creation process, as long as the path can be accessed to each other through the FIFO to communicate with each other, therefore, Processes that are not related to FIFO can also exchange data. But only one node on disk, and the file's data exists only in the memory buffer page, just like a normal pipe.
A pipeline file may have blocking problems reading and writing
For read processes
- If the pipeline is blocked open and the current FIFO has no data, the read process is blocked.
- If non-blocking is turned on, the read operation is performed immediately.
For write processes
- If the pipe is blocked open, it is blocked until it can be written.
- If non-blocking is open and cannot be fully written, the write part or write fails.
The following consists of two programs, one for reading the pipeline and creating the pipeline in the program, and the other for the write pipeline. The first thing to call is to read the program.
Read the program
#include <stdio.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#include<stdlib.h>#include<limits.h>/*created by a read pipeline*/#defineMyfifo "/tmp/myfifo"intMainintargcChar*argv[]) { intFD; CharBuf[pipe_buf]; intnread; /*if the pipeline does not exist, create*/ if(Access (Myfifo, F_OK) = =-1){ /*0 is a pipeline file, 666 is a permission*/ if(Mkfifo (Myfifo,0666) <0) && (errno! =eexist)) {Perror ("Create FIFO"); Exit (1); } } /*read-only blocking way to open a pipeline*/FD=Open (Myfifo, o_rdonly); if(FD = =-1) {perror ("Open"); Exit (1); } /*reading a string*/ while(1) {memset (buf,0,sizeof(BUF)); if((nread = Read (FD, buf, pipe_buf)) >0) {printf ("Read%s\n", BUF); }} close (FD); Exit (0);}
Write a program
#include <stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#include<stdlib.h>#include<limits.h>/*created by a read pipeline*/#defineMyfifo "/tmp/myfifo"intMainintargcChar*argv[]) { intFD; CharBuf[pipe_buf]; intNwrite; if(ARGC <=1) {printf ("Usage:./fifo_write <strring>"); Exit (1); } sscanf (argv[1],"%s", BUF); /*write-only blocking mode to open the pipeline*/FD=Open (Myfifo, o_wronly); if(FD = =-1) {perror ("Open"); Exit (1); } /*Write String*/ if((Nwrite = Write (fd, buf, pipe_buf)) >0) {printf ("write:%s\n", BUF); } close (FD); Exit (0);}
Compile run
-o fifo_read$. /-o fifo_write$. /fifo_write$. /Fifo_write Write 1write: Write 1$. /Fifo_write Write 2write: Write 2$. /Fifo_write Write 3write: Write 3
Linux Pipeline Communication