Directory
1. Inter-process communication
Second, the pipeline
anonymous pipe
named pipe
One, inter-process communication
InterProcess Communication (IPC, InterProcess Communication), that is, the dissemination or exchange of information between different processes; since the general process user address space is independent and cannot directly access the address space of other processes, information exchange between processes must pass through the system Kernel conduct;
Inter-process communication purpose
- Data transfer, sending data from one process to another process;
- Resource sharing, sharing the same resources between multiple processes;
- Notification event, a process sends information to another process or a group of processes to notify them that a certain event has occurred (such as notifying the parent process when the process terminates);
- Process control. Some processes want to completely control the execution of another process (such as debugging). At this time, the process hopes to be able to intercept all exceptions of another process and be able to know its status changes in a timely manner;
Classification of inter-process communication
- pipe
- anonymous pipe
- named pipe
- System V IPC
- system V message queue
- system V shared memory
- system V semaphore
- POSIX IPC
- message queue
- Shared memory
- amount of information
- mutex
- Moderator
- read-write lock
two, pipeline
Anonymous pipe pipe, named pipe;
Anonymous Pipeline
Linux connects multiple commands by using a vertical bar (pipe character | ) to form a pipeline; the output of the command before the pipe character is used as the input of the command after the pipe character, and the data in the pipe can only flow in one direction (that is, half-duplex communication ), two pipes need to be created to achieve bidirectional flow; in addition, this pipe is an anonymous pipe, which will be automatically destroyed when used up, and can only communicate between parent and child processes;
[wz@192 Desktop]$ cat test.c | grep main int main()
The parent process needs to open the file for reading and writing, so that the child process can only read and write when inheriting, and then close the corresponding reading and writing of the parent and child processes to realize the transmission of information; communication can also be done without closing the corresponding reading and writing, but it is generally closed prevent misuse;
pipeline function pipe
- Create an anonymous pipe
- Created successfully, return 0;
- Create failed, return -1;
pipefd is an array of file descriptors
- pipefd[0], specifies the pipe read end, the default value is 3;
- pipefd[1], specifies the write end of the pipe, the default value is 4;
#include <stdio.h> #include <unistd.h> int main() { int pipefd[2]; if(pipe(pipefd) < 0) { perror("pipe"); return 1; } printf("pipefd[0]: %d\\ ", pipefd[0]); printf("pipefd[1]: %d\\ ", pipefd[1]); return 0; }
[wz@192 pipe]$ ./test pipefd[0]: 3 pipefd[1]: 4
int main() { int pipefd[2]; if(pipe(pipefd) < 0){ perror("pipe"); return 1; } char buf[32]; write(pipefd[1],"hellopipe",32); //Write into the pipe read(pipefd[0],buf,32); //read from the pipe printf("buf: %s\\ ", buf); return 0; }
[wz@192 pipe]$ ./test buf: hellopipe
//The child process writes and the parent process reads #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> int main() { int pipefd[2]; if(pipe(pipefd) < 0){ perror("pipe"); return 1; } pid_t id = fork(); if(id < 0){ perror("fork"); return 1; } else if(id == 0){ close(pipefd[0]); char* msg = "child msg"; int count=5; while(count){ printf("child write: %s\\ ",msg); write(pipefd[1],msg,strlen(msg)); sleep(1); count--; } close(pipefd[1]); exit(0); } else{ char buf[64]; close(pipefd[1]); while(1){ ssize_t sz=read(pipefd[0],buf,sizeof(buf)-1); if(sz>0){ buf[sz]=0; printf("father read: %s\\ ",buf); } else if(sz==0){ printf("pipe file empty!\\ "); break; } } close(pipefd[0]); printf("close read\\ "); int status = 0; pid_t wait_pid = waitpid(id, & status,0); if(WIFEXITED(status) & amp; & amp; wait_pid==id) printf("child exit normal, exit code: %d\\ ", WEXITSTATUS(status)); else printf("child exit error, exit sig: %d\\ ", WTERMSIG(status)); } return 0; }
- If the pipe is empty, the reader needs to wait for the data to be ready, that is, read blocks;
- If the pipe is full on the write end, you need to wait for the pipe to have free space before continuing to write, that is, write blocking;
- The pipeline has its own synchronization mechanism;
- Pipes are one-way communication;
- Pipelines are byte stream oriented;
- Pipes can only ensure communication between processes that are related by blood;
- Pipes can ensure a certain degree of atomicity in data reading;
//The child process continues to write, and the parent process closes reading // At this time, the OS will directly close the child process else{ char buf[64]; close(pipefd[1]); while(1){ ssize_t sz=read(pipefd[0],buf,sizeof(buf)-1); if(sz>0){ buf[sz]=0; printf("father read: %s\\ ",buf); close(pipefd[0]); break; } else if(sz==0){ printf("pipe file empty!\\ "); break; } } printf("close read\\ "); int status = 0; pid_t wait_pid = waitpid(id, & status,0); if(WIFEXITED(status) & amp; & amp; wait_pid==id) printf("child exit normal, exit code: %d\\ ", WEXITSTATUS(status)); else printf("child exit error, exit sig: %d\\ ", WTERMSIG(status)); }
//The exit signal of the child process is 13, that is, SIGPIPE [wz@192 pipe]$ ./test child write: child msg father read: child msg close read child write: child msg child exit error, exit sig: 13
[wz@192 pipe]$ ulimit -a core file size (blocks, -c) 0 data segment size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7154 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 4096 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
Named Pipe
Named pipes are a special type of file that can exchange data between unrelated processes and are implemented using FIFO files;
Use the command mkfifo to create a named pipe
[wz@192 pipe]$ mkfifo pipefile [wz@192 pipe]$ ll pipefile prw-rw-r--. 1 wz wz 0 August 18 08:24 pipefile
Use the function mkfifo to create a named pipe
The difference between anonymous pipes and named pipes
- Anonymous pipes are created and opened by the function pipe;
- The named pipe is created by the function or command mkfifo, and then opened by open;
- The only difference is the creation and opening methods;
[wz@192 pipe]$ echo abc > pipefile
[wz@192 pipe]$ while:; do echo "1,##########"; cat pipefile; echo "2,#########\ "; sleep 1; done 1,########## abc 2,######### 1,##########
Implement server & client communication
//makefile .PHONY:all all: server client server:server.c gcc -o $@ $^ client:client.c gcc -o $@ $^ .PHONY:clean clean: rm -rf server client
//server.c //Create a named pipe and read #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { int ret = mkfifo("pipefile", 0644); if(ret == -1){ perror("mkfifo"); return 1; } int pipefd = open("pipefile", O_RDONLY); if(pipefd < 0){ perror("open"); return 2; } char msg[64]={0}; while (1) { printf("please wait ...\\ "); ssize_t sz = read(pipefd, msg, sizeof(msg)-1); if(sz > 0){ msg[sz]=0; printf("server read: %s\\ ", msg); } else if(sz == 0){ printf("client quit!\\ "); break; } else { perror("read"); return 3; } } close(pipefd); return 0; }
//client.c //Write to the pipe #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { int pipefd = open("pipefile", O_WRONLY); if(pipefd < 0){ perror("open"); return 1; } char msg[64]={0}; while(1){ printf("please write ...\\ "); ssize_t sz = read(0, msg, sizeof(msg)-1); if(sz>0){ msg[sz]=0; write(pipefd, msg, strlen(msg)); } else if(sz==0){ printf("client read empty!\\ "); break; } else{ perror("client read\\ "); return 2; } } close(pipefd); return 0; }