【回眸】技术干货——Linux内核(十二) 进程间通讯 之 管道
前言
进程的介绍已经告一段落,接下来学习的内容是进程间的通讯.
进程间通信(IPC)
面试考点:
IPC的通讯方式通常有:管道(无名和命名) ,消息队列,信号量,共享存储,socket,streams等.socket和streams支持2个不同的主机上的2个进程IPC.
管道通常指无名管道
特点:
- 半双工(只能在一个方向上流动)
- 只能用于具有亲缘关系的进程间通讯(父子进程or兄弟进程)
- 读写可用 read write 等函数,不属于其他任何文件系统,只存在于内存中.
局限性:
1.同一时间只能单向(eg:父进程读,子进程写);
2.管道数据,读完就没了
函数原型:
#include <unistd.h>int pipe(int fd[i]); fd[0]为读而打开 ------>关闭--------> close fd[0] fd[1]为写而打开 ------>关闭--------> close fd[1]
无名管道函数应用:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> int main (){ int fd[2]; int pid ; char buf[128]; if (pipe(fd) == -1){ printf("create pipe failed!\n"); } pid = fork(); if (pid < 0){ printf ("create child progress failed!\n"); } else if(pid > 0){ printf("this is father progress!\n"); close(fd[0]); write(fd[1],"hello from father",strlen("hello from father")); wait(&pid); } else{ printf("this is child progress!\n"); close(fd[1]); read(fd[0],buf,128); printf("read from father:%s!\n",buf); exit(0); } return 0; }
运行结果展示:
命名管道(FIFO)
FIFO也称命名管道,是一种文件类型.
特点
- FIFO 可以在无关的进程之间交换数据,与无名管道不同.
- FIFO 有路径名与之相关连,它以一种特殊的设备文件形式存在与文件系统中.
函数原型
#include <sys/stat.h>int mkfifo(const char* pathname,moode_t mode); //成功返回值为0,失败返回值为-1命名管道以文件的形式存储在磁盘,所以在创建FIFO之后可以用一般的I/O函数操作它.
一般read之后都会阻塞,等读取到write内容后才会回复正常.
也可以设置成非阻塞,但是不经常用于FIFO.
有名管道函数应用:
comm3.c
#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> int main(){ if (mkfifo("./file",0600) == -1 && errno!= EEXIST) { printf("mkfifo failed \n"); perror("why"); } int fd =open ("./file",O_RDONLY); printf ("open successfully!\n "); return 0; }
comm4.c
#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> int main(){ int fd =open ("./file",O_WRONLY); printf ("write open successfully!\n "); return 0; }
运行编译命令及运行结果展示:
命名管道(持续收发版)
comm5.c(read)
#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> int main(){ char buf[30] = {0}; int nread = 0; if (mkfifo("./file",0600) == -1 && errno!= EEXIST) { printf("mkfifo failed \n"); perror("why"); } int fd =open ("./file",O_RDONLY); printf ("open successfully!\n "); while(1){ nread = read(fd,buf,30); printf("Read %d byte from fifo,context = %s \n",nread,buf); } close(fd); return 0; }
comm6.c(write)
#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <unistd.h> int main(){ int cnt = 0; char *str = "message from fifo."; int fd =open ("./file",O_WRONLY); printf ("write open successfully!\n "); while(1){ write(fd,str,strlen(str)); sleep(1); cnt = cnt + 1; if (cnt == 5){ break; } } close(fd); return 0; }
运行编译命令及运行结果参考:
上述代码是写5遍,写完后不停读取,读完之后就读不到内容了。
后记碎碎念
Linux是一个系列,可以点击专栏查看同系列的其他文章,希望能帮到屏幕前的每一位应届生往届生,该博文最初发表在CSDN上。
#租房前辈的忠告##校招求职有谈薪空间吗##找工作前vs找工作后的心路变化##26届秋招投递记录##央国企投递记录#本专栏助应届生从物联网小白成长为企业争抢的技术人才,聚焦三大核心技术:传感器应用(环境监测)、嵌入式开发(STM32/Arduino)、通信协议(LoRa/NB-IoT/MQTT),配合10+实战项目(如智能温湿度监控系统)积累项目经验。覆盖智能硬件、工业物联网、智能家居领域岗位需求,解析企业招聘技术重点与面试题,帮电子、计算机、自动化等专业学生构建知识体系,提前锁定名企Offer!