进程间通信(IPC)就是指不同进程之间传播和交换数据,每个进程各自有不同的用户地址空间(虚拟地址空间),任何一个进程的全局变量在另一个进程中都看不到,所以进程间要交换数据必须能通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷贝到内核缓冲区,进程B再把数据从内核缓冲区拷贝到自己的用户空间,内核提供的这种机制称为进程间通信;Linux下IPC机制主要分为:管道、信号量、共享内存、消息队列、套接字;
一、管道
1 思想:调用pipe函数会在内核开辟出一块缓冲区称之为管道文件,包含一个读端和一个写端,进程间可以通过该缓冲区进行通信;
2 特点:半双工形式、父子进程、自带同步机制;
3 用法:父进程调用pipe创建管道,得到两个文件描述符fd[2],fd[0]可读,fd[1]可写;父进程fork出子进程,子进程也同样得到两个描述符fd[2];父进程关闭读端fd[0],子进程关闭写端fd[1],这样父进程往管道里写数据,子进程从管道里读数据,管道是用环形队列实现的,数据从写端流入,从读端流出;说明如下:
(1)读管道时,若管道为空则阻塞,直到写端write将数据写入到管道;若写端被关闭则返回0;
(2)写管道时,若管道已满则阻塞,直到读端read将管道内数据取走;若读端被关闭则返回错误-1,产生信号SIGPIPE;
4 代码实现如下:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 5 #define ABCDE "abcde" 6 #define FGHIJ "fghij" 7 8 int main(int argc, char *argv[]) 9 { 10 int fd[2] = {0}, size = 0; 11 pid_t pid = -1; 12 char buf[256] = {0}; 13 14 if(pipe(fd)) //1 pipe 15 { 16 perror("pipe"); 17 return 1; 18 } 19 pid = fork(); //2 fork 20 if(pid < 0) 21 { 22 perror("fork"); 23 return 2; 24 } 25 else if (pid == 0)//3 child write fd[1] 26 { 27 printf("child start\n"); 28 close(fd[0]); 29 size = write(fd[1], ABCDE, 5); 30 printf("child,msg=%s,size=%d\n", ABCDE, size); 31 //sleep(1); 32 size = write(fd[1], FGHIJ, 5); 33 printf("child,msg=%s,size=%d\n", FGHIJ, size); 34 } 35 else //3 father read fd[0] 36 { 37 printf("father start\n"); 38 close(fd[1]); 39 //sleep(1); 40 size = read(fd[0], buf, 256); //block until child write to fd[1] 41 printf("father,msg=%s,size=%d\n", buf, size); 42 memset(buf, 0, sizeof(buf)); 43 size = read(fd[0], buf, 256); //block until child write to fd[1] 44 printf("father,msg=%s,size=%d\n", buf, size); 45 } 46 return 0; 47 }
二、