What makes the desert beautiful is that somewhere it hides a well.
The desert is beautiful because there is a well hidden somewhere in it.
Linux process and process communication programming (2)
- interprocess communication
-
- 1. Pipeline communication
-
- (1) Famous pipeline
-
- mkfifo
- 21write.c , 21read.c code
- (2) Anonymous pipe
-
- 20.c code
- 2. Signal communication
-
- (1) Signal sending
-
- raise
- 22.1.c code
- kill
- 22-2.c, 22-3.c code
- alarm
- 22-4.c code
- (2) Signal reception
-
- use pause
- 22-5.c code
- (3) Signal processing
-
- use signal
- 22-6.c code
- 3. Shared memory
-
- Create shared memory
-
- shmget
- 24-1.c code
- shmat
- shmdt
- shmctl
Interprocess communication
1. Pipeline communication
Process A and process B belong to the application layer and cannot communicate directly
Pipes are used for communication between them, pipes exist in the kernel
Regardless of whether it is named or unnamed, as long as there is no content in the pipeline, the use of the read function will be blocked
(1) Famous pipeline
Can be used for any two processes
Related programs 21write.c , 21read.c
mkfifo
//header file #include <sys/stat.h> #include <unistd.h>
You have to write and read at the same time to read
21write.c, 21read.c code
21write.c
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> //for close, read, write, fork int main(int argc, char *argv[]) {<!-- --> char buf[32] = {<!-- -->0}; int fd; int ret; if (argc < 2) {<!-- --> printf("Input fifo file name:\\ "); //Input parameters are too few, give a prompt printf("argc:%d\\ ", argc); } else if (argc = 2) {<!-- --> printf("argc:%d\\ ", argc); if (access(argv[1], F_OK) == -1) {<!-- --> // access is used to determine whether there is a fifo file for keyboard input ret = mkfifo(argv[1], 0666); //If it does not exist, create a pipeline file if (ret == -1) {<!-- --> printf("Error"); } else printf("The pipeline is built"); } fd = open(argv[1], O_WRONLY); write(fd, "hello111", 8); close(fd); } }
21read.c
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> //for close, read, write, fork int main(int argc, char *argv[]) {<!-- --> char buf[32] = {<!-- -->0}; int fd; int ret; if (argc < 2) {<!-- --> printf("Input the file name of fifo:\\ "); //There are too few input parameters, just give a prompt } else if (argc = 2) {<!-- --> fd = open(argv[1], O_RDONLY); read(fd, buf, 32); printf("buf:%s\\ ", buf); close(fd); } }
(2) Nameless pipe
for parent and child processes
Related program 20.c
The unnamed pipe is created before the child process
If the parent process is blocked, the program will always be stuck
When the parent process writes, the child process can read it
20.c code
//Unnamed pipe #include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> //for pid_t #include <sys/stat.h> #include <sys/wait.h> #include <unistd.h> //for close, read, write, fork int main() //No parameters {<!-- --> char buf[32]={<!-- -->0}; int fd[2]; //Define the descriptors at both ends of the pipeline, there are two pipe(fd); //create pipeline printf("fd[0]:%d\\ ",fd[0]); // print fd at the reading end printf("fd[1]:%d\\ ", fd[1]); //print the fd on the write side pid_t pid; //Define a pid to receive the return value of fork pid = fork(); if (pid < 0) {<!-- --> printf("Failed to create"); } // parent process if (pid > 0) {<!-- --> write(fd[1],"hello",5); } //child process if (pid == 0) {<!-- --> close(fd[1]); //Close the write terminal, only read read(fd[0],buf,32); printf("buf:%s\\ ",buf); close(fd[0]); } }
2. Signal communication
Which signal to use, you can check it online
(1) Signal sending
//header file #include <sys/types.h> #include <signal.h> #include <unistd.h>
raise
used to signal oneself
Related procedure 22.1.c
22.1.c code
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> int main() {<!-- --> printf("raise before\\ "); raise(9); // raise means that the signal sent by oneself cannot be captured, and the 9 in it means to terminate the process printf("raise after\\ "); }
kill
It is used to kill the process, which has the same effect as the kill command
Related Procedure 22-2.c
Use 22-2.c to kill the process of 22-3.c
22-2.c, 22-3.c code
22-2.c
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> int main(int argc, char *argv[]) {<!-- --> pid_t pid; int sig; if(argc<3){<!-- --> printf("Enter the process pid and signal type\\ "); } sig=atoi(argv[2]); pid = atoi(argv[1]); kill(pid,sig); }
22-3.c
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> int main() {<!-- --> while(1){<!-- --> sleep(1); printf("hh\\ "); } }
alarm
Similar to setting an alarm clock, kill the process when the time is up
Related program 22-4.c
22-4.c code
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> int main() {<!-- --> int i; alarm(4); //indicates to kill the process at 4s while (1) {<!-- --> sleep(1); i + + ; printf("i:%d\\ ",i); } }
(2) Signal reception
A process takes a long time to receive a signal
For example, use while (1), sleep (x) (running in x seconds), pause (sleep all the time)
When the process is running, press ctrl + c, enter kill, and the process can receive these signals
use pause
It is used to let the process run halfway and enter the dormant state, and it will remain dormant, and exit with signal or ctrl + c
Related procedure 22-5.c
22-5.c code
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> int main() {<!-- --> printf("before pause\\ "); pause(); // pause means enter sleep printf("after pause\\ "); }
(3) Signal processing
default (terminate) , ignore , capture
Use signal
Related program 22-6.c
//header file #include <signal.h>
default
signal(SIGINT,SIG_DFL); //SIGINT means ctrl + c, SIG_DFL means to execute the default operation of ctrl + c, which is to terminate
neglect
signal(SIGINT,SIG_IGN); //SIGINT means ctrl + c, SIG_IGN means ignore ctrl + c signal
capture
signal(SIGINT,myfun); //Catch the signal SIGINT, and then execute the code in myfun //For example, press ctrl + c to execute another cycle
22-6.c code
#include <stdio.h> //for main function #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> // void fun(int sig){ // if(sig==SIGINT){<!-- --> // while (1) // {<!-- --> // printf("hei hei\\ "); // sleep(2); // } // } // } int main() {<!-- --> // signal(SIGINT,SIG_IGN); //ignore // signal(SIGINT, SIG_DFL); //default // signal(SIGINT, fun); // execute new function while (1) {<!-- --> printf("hh\\ "); sleep(2); } }
3. Shared memory
for inter-process communication
Create shared memory
shmget
Related procedure 24-1.c
//header file #include <sys/ipc.h> #include <sys/shm.h>
Use macros as key values
Use ftok return value as key value
24-1.c code
//Create shared memory, use macro as key value #include <stdio.h> //for main function #include <stdlib.h> #include <sys/ipc.h>//for shmget #include <sys/shm.h> #include <sys/types.h> int main() {<!-- --> int id; id = shmget(IPC_PRIVATE, 1024, 0777); // IPC_PRIVATE uses macros as key values if (id < 0) {<!-- --> printf("Failed to create shared memory\\ "); } else printf("id:%d\\ ", id); }
shmat
Used to map shared memory in the kernel to user space
shmdt
Delete the address of the shared memory mapping
shmctl
Delete the shared memory address in the kernel