通信方式分4大类:
管道通信:无名管道 有名管道
信号通信:发送 接收 和 处理
IPC通信:共享内存 消息队列 信号灯
socke 网络通信
用户空间 进程A <----无法通信----> 进程B -----------------|--------------------------------------|-------------- | | 内核空间 |<-------------> 对象 <--------------->| ---------------------------------------------------------------------- //基于文件IO的思想 //open 打开或者创建一个文件,内核开辟一个buffer -->打开对象 //write 往buffer里面写 //read 从buffer读 //close 释放buffer
用户空间 进程A <----无法通信----> 进程B -----------------|--------------------------------------|-------------- | | 内核空间 |<-------------> 管道 <--------------->| ---------------------------------------------------------------------- 管道文件时一个特殊的文件,由队列来实现 open --> pipe 管道中的东西读完了,就删除了、 管道中如果没有东西可读,就会 读堵塞 管道中如果写满了,就会写阻塞
无名管道用于父子进程带有亲缘关系的进程
#include <unistd.h> int pipe(int fildes[2]); //创建 //文件描述符 filds[0]-read--出队 filds[1]-write--入队 write(); //写 read(); //读 close(fd[0]); close(fd[1]); ------------------------------ fd[1]write fd[0]read ------------------------------
小例子
int main() { int fd[2]; //pipe的2个文件描述符 int ret; ret = pipe(fd); //创建管道 if(ret < 0){ perror("pipe"); return -1; } printf("fd[0] = %d, fd[1] = %d ",fd[0],fd[1]); return 0; }
#include <stdio.h> #include <string.h> #include <unistd.h> int main(int argc, char const *argv[]) { int fd[2]; int ret; const char *writebuf = "hello pipe"; char readbuf[1024] = {0}; //1,创建pipe ret = pipe(fd); if(ret < 0) { perror("pipe"); return -1; } printf("fd[0] = %d,fd[1] = %d ",fd[0],fd[1]); //2.write ret = write(fd[1],writebuf,strlen(writebuf)); if(ret < 0){ perror("write"); } //2.read ret = read(fd[0],readbuf,1024); if(ret < 0){ perror("read"); return -1; } printf("read: %s ",readbuf); //3.close close(fd[0]); close(fd[1]); return 0; }
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *path, mode_t mode); //文件路径 文件权限
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char const *argv[]) { int ret; //0=ok -1=failes ret = mkfifo("./fifo",0755); //创建管道文件 路径+权限 if(ret < 0){ perror("mkfifo"); return -1; } return 0; }
例子
fifo.c 创建有名管道文件
lude <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char const *argv[]) { int ret; ret = mkfifo("./fifo",0755); //创建管道文件 路径+权限 if(ret < 0){ perror("mkfifo"); return -1; } return 0; }
first.c 进程1
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char const *argv[]) { int fd; int process_int = 0; fd = open("./fifo",O_WRONLY); //注,有名管道两端成对打开时才会开始执行 if(fd < 0){ perror("open"); return -1; } puts("fifo open success."); for(int i=0;i<5;i++){ puts("我是第一个进程"); } sleep(5); process_int = 1; write(fd,&process_int,1); while(1); return 0; }
second.c 进程2
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char const *argv[]) { int fd; int process_int = 0; fd = open("./fifo",O_RDONLY); //注,有名管道两端成对打开时才会开始执行 if(fd < 0){ perror("open"); return -1; } puts("fifo open success."); read(fd,&process_int,1); while(process_int == 0); for(int i=0;i<5;i++){ puts("我是第二个进程"); } while(1); return 0; }