【Linux】进程间通信(管道)
2021/11/25 7:14:37
本文主要是介绍【Linux】进程间通信(管道),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- (一)管道
- (二)管道的分类
- (1)有名管道
- (2)无名管道
- (3)管道的特点
- (4)管道的实现
(一)管道
管道可以在两个进程间传递数据,比如ls -l | grep main.c,其中的"|"就是管道。
上述命令的意思就是查看当前所在目录的结果写入管道,然后grep再从管道中过滤得到main.c的文件显示在屏幕上;
(二)管道的分类
(1)有名管道
- 创建方式
- 命令创建
mkfifo FIFO
- 系统调用创建
int mkfifo(const char* filename, mode_t mode);
头文件(sys/types.h sys/stat.h)
- 进程a从键盘获取数据,通过管道发送给进程b进行输出
a.c
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> void Send() { int fd = open("FIFO", O_WRONLY); if(fd == -1) return; printf("input data:"); while(1) { char buff[128] = {0}; fgets(buff, 127, stdin); if(strncmp(buff, "end", 3) == 0) { break; } write(fd, buff, strlen(buff) - 1); } close(fd); } int main() { Send(); return 0; }
b.c
#include <stdio.h> #include <fcntl.h> #include <string.h> #include <unistd.h> void Recv() { int fd = open("FIFO", O_RDONLY); if(fd == -1) return; printf("reading data...\n"); while(1) { char buff[128] = {0}; int ret = read(fd, buff, 127); if(ret <= 0) break; if(strncmp(buff, "end", 3) == 0) { break; } printf("%s\n", buff); } close(fd); } int main() { Recv(); return 0; }
- 结果:
(2)无名管道
-
无名管道主要用于父子进程间通信
-
创建方式:
- 头文件 unistd.h
- 系统调用
int pipe(int pipefd[2]);
- pipe()返回值:成功0,失败-1
- fd[0]管道读端
- fd[1]管道写端
- 代码
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <signal.h> #include <sys/wait.h> void fun(int sig) { int status; while(waitpid(-1, &status, WNOHANG) > 0); } void DataTransmission() { int fd[2]; int ret = pipe(fd); if(ret == -1) { printf("pipe err\n"); return; } //注册SIGCHLD信号应答 signal(SIGCHLD, fun); pid_t pid = fork(); if(pid == -1) { printf("fork err\n"); return; } if(pid == 0) { //子进程当作写端 close(fd[0]); while(1) { printf("child input data:\n"); char buff[128] = {0}; fgets(buff, 127, stdin); if(strncmp(buff, "end", 3) == 0) { break; } write(fd[1], buff, strlen(buff) - 1); } //关闭写端 close(fd[1]); //退出子进程,自动向父进程发送SIGCHLD信号 exit(0); } //父进程 else { //关闭写端 close(fd[1]); while(1) { char buff[128] = {0}; int ret = read(fd[0], buff, 127); if(ret <= 0) return; if(strncmp(buff, "end", 3) == 0) break; printf("father read data:%s\n", buff); } close(fd[0]); } } int main() { DataTransmission(); return 0; }
- 结果:
(3)管道的特点
- 有名管道、无名管道写入管道的数据都存放在内存中
- 管道是一种半双工通信方式(通信方式有单工、半双工、全双工)
- 有名管道与无名管道区别:有名管道可以在任意进程间使用,而无名管道在父子进程间通信。
(4)管道的实现
这篇关于【Linux】进程间通信(管道)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法