【回眸】技术干货——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!

