Early communication between processes

Foreword:

1. Inter-process communication is divided into three categories:

Early days: unnamed pipes (pipe) , named pipes (fifo) and signals (signal)

System 5 IPC objects: shared memory , message queue, and semaphore

Network : socket

2. Pipeline:

Pipes are a method of process communication in Linux. They connect the output of one program directly to the input of another program. There are two main types of pipeline communication in Linux: named pipes, unnamed pipes, and the pipe file indicator TT.

1. Unnamed pipeline

1. Introduction to nameless pipes:

Unnamed pipes are an original way of Linux communication and have the following characteristics:

(1) Communication can only occur between processes that have a relationship (father-child process or sibling process)

(2) It is simplex (one end receives and one end sends), with fixed reading end and writing end.

(3) The pipe can also be regarded as a special file, and its read(), write() and other functions can also be used for its reading and writing, but it does not belong to any system file and only exists in the memory.

Model:

pipe function:

 pipe:创建无名管道
      #include <unistd.h>
        int pipe(int pipefd[2]);
        功能: 
            创建无名管道 
                     
        参数: 
            pipefd[2]:整型数组
               存放两个文件描述符:一个负责读 一个负责写 
                        [0]--->读取 
                        [1]--->写入 
                                        
          返回值: 
               成功返回0 
               失败返回-1,并设置错误码

2. Test code:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(){
    //制作无名管道需要用到整型数组 ,一个写,一个读
    int pipefd[2];
    
    //创建无名管道 ,返回值为0则创建成功
    int ret=pipe(pipefd);
    if(ret<0){
        perror("pipe");
        return -1;
    }
    
    printf("[0]:%d\n",pipefd[0]);
    printf("[1]:%d\n",pipefd[1]);
    
    //开出父子进程,父子进程依赖无名管道进行通信 
    pid_t pid=fork();//开出父子进程 
    if(pid>0){
       //父进程的操作 :发送信息给子进程
       char buf[50]="";
        while(1){
			//bzero 清空数组内存垃圾值
            bzero(buf,sizeof(buf));
            scanf("%s",buf);
            write(pipefd[1],buf,strlen(buf));
        }
       
    }else if(pid==0){
       //子进程的操作,读取无名管道中的内容
       char buf[50];
       while(1){
           bzero(buf,sizeof(buf));
           read(pipefd[0],buf,sizeof(buf));
           printf("子进程收到:%s\n",buf);
       }
    }else{
        perror("fork");
        exit(-1);
    }
       
    return 0;
}

3. Note on pipeline reading and writing

When there is no data in the pipe, the read operation blocks
When writing data to the pipe, Linux will not guarantee the atomicity of the write. As soon as there is a free area in the pipe buffer, the writing process will try to
Write data to the pipe. If the reading process does not read the data in the pipe buffer, the write operation will remain blocked.
Writing data to a pipe only makes sense if the read end of the pipe exists. Otherwise, the process writing data to the pipe will receive
SIFPIPE signal sent from the kernel ( usually Broken pipe error ) .

2. Famous channels

1. Characteristics of famous pipelines

Named pipes (FIFO) are an improvement over unnamed pipes and have the following characteristics:

(1) Realize communication between two unrelated processes.

(2) The pipe can be pointed out by the path and is visible in the system. After it is established, the two processes can use it as an ordinary file for reading and writing operations.

(3) FIFO strictly follows the first-in-first-out rule and does not support operations (positioning) such as lseek() .

Model:

2. Test:

 

Communication method 1:

#include <stdio.h>
#include <sys/types.h>//mkfifo头文件
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc,char *argv[]){
    if(argc!=2){
        printf("User:%s <file_name> \n",argv[0]);
        return 0;
    }
    //创建管道文件(利用某一个文件名只能创建一次的特性)
    if(access(argv[1],F_OK)){  //判断argv[1]是否已经存在
            if(mkfifo(argv[1],0666)){
                perror("mkfifo");
                exit(-1);
            }
    }
    
    
    //2>利用有名管道进行进程间通信 
    int fd=open(argv[1],O_RDWR);
    if(fd<0){
        perror("open");
        exit(-1);
    }
    //3>往有名管道里写入数据 
    char buf[50]="";
    while(1){
        bzero(buf,sizeof(buf));
        scanf("%s",buf);
        write(fd,buf,strlen(buf));
        }
    
    return 0;
}

Communication method 2:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc,char *argv[]){
    if(argc!=2){
        printf("User:%s <file_name> \n",argv[0]);
        return 0;
    }
    //创建管道文件(利用某一个文件名只能创建一次的特性)
    if(access(argv[1],F_OK)){  //判断argv[1]是否已经存在
            if(mkfifo(argv[1],0666)){
                perror("mkfifo");
                exit(-1);
            }
    }
    
    //2>利用有名管道进行进程间通信 
    int fd=open(argv[1],O_RDWR);
    if(fd<0){
        perror("open");
        exit(-1);
    }
    //3>往有名管道里读取数据 
       char buf[50];
       while(1){
           bzero(buf,sizeof(buf));
           read(fd,buf,sizeof(buf));
           printf("%s\n",buf);
       }
    
    return 0;
}

3. Read operation:


3. Signal communication

1 Overview:

        Signal is a simulation of the interrupt mechanism at the software level and an asynchronous communication method. Signals can directly interact between user space processes and kernel processes, and kernel processes can also use them to notify user space processes of what system events have occurred.
          If the process is not currently executing, the signal is saved by the kernel until the process resumes execution and then delivered to it; if a signal is set to be blocked by the process, the delivery of the signal is delayed until its blocking is cleared. It is only passed to the process when cancelled.

2. Life cycle:

 3. Signal response:

(1) Ignore the signal: No processing is performed on the signal, but there are two signals that cannot be ignored: SIGKILL and SIGSTOP .

(2) Capture the signal: Define the signal processing function. When the signal occurs, execute the corresponding processing function.

(3) Perform default operations: Linux provides default operations for each signal.

4. Signal detection and processing process:

 

5. Types of signals:

 Commonly used signals:

1) SIGHUP ;--->终端在关闭时,给其下所有的进程发送信号 
2) SIGINT :--->结束进程  就是:ctrl + c 
3) SIGQUIT: --->结束进程  就是:ctrl + \
9) SIGKILL: --->强制杀死进程  不能被注册,不能被忽略 --->signal 
10) SIGUSR1:--->用户自定义信号  --->signal
12) SIGUSR2:--->用户自定义信号  --->signal
14) SIGALRM:-->闹钟信号,用来倒计时,当到0后,触发信号,结束进程 
17) SIGCHLD:--->子进程结束时,给父进程发送的信号 
18) SIGCONT:--->继续进程 
19) SIGSTOP:--->暂停进程: 不能被注册,不能被忽略 --->signal
20) SIGTSTP:-->暂停进程: ctrl + z

6. Send signal:

                1>发送信号 
                   kill
                   #include <sys/types.h>
                   #include <signal.h>
                   int kill(pid_t pid, int sig);
                   功能: 
                        发送信号 
                        
                   参数: 
                           pid:接收信号的进程PID:发送给谁 
                           sig:发送的信号是什么
                           
                   返回值: 
                           成功返回0 
                           失败返回-1,并设置错误码
                           
                2>函数转换类型: 
                    atoi --->char型转int型
                    #include <stdlib.h>
                    int atoi(const char *nptr);
                    功能: 
                          将接收到的char型转化为int型 
                          
                    参数: 
                            nptr:接受到的char型 
                            
                    返回值: 
                            成功返回转化后int型
                            失败返回-1,并设置错误码
                            
                    从左往右进行转换的

7. Signal processing: signal() function:

                        信号注册:
                        signal
                        #include <signal.h>
                       typedef void (*sighandler_t)(int);
                       sighandler_t signal(int signum, sighandler_t handler);
                       功能: 
                            信号注册 
                            
                       参数: 
                             signum:需要操作的信号 
                             handler:注册事件 
                                   SIG_IGN:忽略 
                                   SIG_DFL:默认:恢复  
                                   捕捉:注册:执行自己写的一个函数
                                   typedef void (*sighandler_t)(int);--->函数指针
                                   
                       返回值: 
                            成功返回sighandler_t类型 
                            失败返回-1,并设置错误码\

8. Timer function:

        pause function, alarm function:                  

#include <unistd.h>
            int pause(void);
            功能:
                    将进程挂起(休眠等待唤醒)--->阻塞 
                    唤醒:捕捉信号,执行该信号则解除挂起-->唤醒
               
            参数: 
                   void
                    
            返回值: 
                    成功返回0 
                    失败返回-1,并设置错误码
            
            
            alarm
            #include <unistd.h>
            unsigned int alarm(unsigned int seconds);
            功能: 
                    倒计时(计时器)
                    当倒计时到0时,触发SIGALRM信号,结束进程 
                    
            参数: 
                    seconds:秒数 
                    
            返回值: 
                    第一次调用返回0
                    二次调用以上,返回剩余秒数

9. Test: Code:

When the parent process receives the cltr+c operation, the child process prints: We are going to Wa State to make a fortune.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
//收到信号后执行的函数,通过信号注册传递
void showMsg(int sig){
        printf("我们要去佤邦发财啦!\n");
}
//捕捉信号
void sendMsg(int sig){
    kill(getppid(),SIGUSR1);
}

int main(){
    //因为操作要开出父子进程:fork 
    pid_t pid=fork();
    if(pid>0){
        //父进程操作
        signal(SIGUSR1,showMsg);
        signal(SIGINT,SIG_IGN);
    }else if(pid==0){
        //子进程的操作
        signal(SIGINT,sendMsg);
    }
    
    while(1){
      //防止过快,显示,也可以用pause()函数  
    }
    return 0;
}

 


Guess you like

Origin blog.csdn.net/apple_71040140/article/details/132510197