C/C++ 进程间通信 管道
使用匿名管道
- #include <stdio.h>
- FILE* popen (const char *command, const char *open_mode);
- int pclose(FILE *stream_to_close);
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- FILE *read_fp = NULL;
- FILE *write_fp = NULL;
- char buffer[BUFSIZ + 1];
- int chars_read = 0;
- //初始化缓冲区
- memset(buffer, '\0', sizeof(buffer));
- //打开ls和grep进程
- read_fp = popen("ls -l", "r");
- write_fp = popen("grep rwxrwxr-x", "w");
- //两个进程都打开成功
- if(read_fp && write_fp)
- {
- //读取一个数据块
- chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
- while(chars_read > 0)
- {
- buffer[chars_read] = '\0';
- //把数据写入grep进程
- fwrite(buffer, sizeof(char), chars_read, write_fp);
- //还有数据可读,循环读取数据,直到读完所有数据
- chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
- }
- //关闭文件流
- pclose(read_fp);
- pclose(write_fp);
- exit(EXIT_SUCCESS);
- }
- exit(EXIT_FAILURE);
- }
3、popen的实现方式及优缺点
- #include <unistd.h>
- int pipe(int file_descriptor[2]);
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- int data_processed = 0;
- int filedes[2];
- const char data[] = "Hello pipe!";
- char buffer[BUFSIZ + 1];
- pid_t pid;
- //清空缓冲区
- memset(buffer, '\0', sizeof(buffer));
- if(pipe(filedes) == 0)
- {
- //创建管道成功
- //通过调用fork创建子进程
- pid = fork();
- if(pid == -1)
- {
- fprintf(stderr, "Fork failure");
- exit(EXIT_FAILURE);
- }
- if(pid == 0)
- {
- //子进程中
- //读取数据
- data_processed = read(filedes[0], buffer, BUFSIZ);
- printf("Read %d bytes: %s\n", data_processed, buffer);
- exit(EXIT_SUCCESS);
- }
- else
- {
- //父进程中
- //写数据
- data_processed = write(filedes[1], data, strlen(data));
- printf("Wrote %d bytes: %s\n", data_processed, data);
- //休眠2秒,主要是为了等子进程先结束,这样做也只是纯粹为了输出好看而已
- //父进程其实没有必要等等子进程结束
- sleep(2);
- exit(EXIT_SUCCESS);
- }
- }
- exit(EXIT_FAILURE);
- }
使用命名管道
- #include <sys/types.h>
- #include <sys/stat.h>
- int mkfifo(const char *filename, mode_t mode);
- int mknod(const char *filename, mode_t mode | S_IFIFO, (dev_t)0);
- open(const char *path, O_RDONLY);//1
- open(const char *path, O_RDONLY | O_NONBLOCK);//2
- open(const char *path, O_WRONLY);//3
- open(const char *path, O_WRONLY | O_NONBLOCK);//4
- #include <unistd.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <string.h>
- int main()
- {
- const char *fifo_name = "/tmp/my_fifo";
- int pipe_fd = -1;
- int data_fd = -1;
- int res = 0;
- const int open_mode = O_WRONLY;
- int bytes_sent = 0;
- char buffer[PIPE_BUF + 1];
- if(access(fifo_name, F_OK) == -1)
- {
- //管道文件不存在
- //创建命名管道
- res = mkfifo(fifo_name, 0777);
- if(res != 0)
- {
- fprintf(stderr, "Could not create fifo %s\n", fifo_name);
- exit(EXIT_FAILURE);
- }
- }
- printf("Process %d opening FIFO O_WRONLY\n", getpid());
- //以只写阻塞方式打开FIFO文件,以只读方式打开数据文件
- pipe_fd = open(fifo_name, open_mode);
- data_fd = open("Data.txt", O_RDONLY);
- printf("Process %d result %d\n", getpid(), pipe_fd);
- if(pipe_fd != -1)
- {
- int bytes_read = 0;
- //向数据文件读取数据
- bytes_read = read(data_fd, buffer, PIPE_BUF);
- buffer[bytes_read] = '\0';
- while(bytes_read > 0)
- {
- //向FIFO文件写数据
- res = write(pipe_fd, buffer, bytes_read);
- if(res == -1)
- {
- fprintf(stderr, "Write error on pipe\n");
- exit(EXIT_FAILURE);
- }
- //累加写的字节数,并继续读取数据
- bytes_sent += res;
- bytes_read = read(data_fd, buffer, PIPE_BUF);
- buffer[bytes_read] = '\0';
- }
- close(pipe_fd);
- close(data_fd);
- }
- else
- exit(EXIT_FAILURE);
- printf("Process %d finished\n", getpid());
- exit(EXIT_SUCCESS);
- }
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <limits.h>
- #include <string.h>
- int main()
- {
- const char *fifo_name = "/tmp/my_fifo";
- int pipe_fd = -1;
- int data_fd = -1;
- int res = 0;
- int open_mode = O_RDONLY;
- char buffer[PIPE_BUF + 1];
- int bytes_read = 0;
- int bytes_write = 0;
- //清空缓冲数组
- memset(buffer, '\0', sizeof(buffer));
- printf("Process %d opening FIFO O_RDONLY\n", getpid());
- //以只读阻塞方式打开管道文件,注意与fifowrite.c文件中的FIFO同名
- pipe_fd = open(fifo_name, open_mode);
- //以只写方式创建保存数据的文件
- data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644);
- printf("Process %d result %d\n",getpid(), pipe_fd);
- if(pipe_fd != -1)
- {
- do
- {
- //读取FIFO中的数据,并把它保存在文件DataFormFIFO.txt文件中
- res = read(pipe_fd, buffer, PIPE_BUF);
- bytes_write = write(data_fd, buffer, res);
- bytes_read += res;
- }while(res > 0);
- close(pipe_fd);
- close(data_fd);
- }
- else
- exit(EXIT_FAILURE);
- printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);
- exit(EXIT_SUCCESS);
- }
但是为了数据的安全,我们很多时候要采用阻塞的FIFO,让写操作变成原子操作。
转载于:https://www.cnblogs.com/dk666/p/7412527.html
C/C++ 进程间通信 管道相关推荐
- Linux下进程间通信——管道
进程间通信 一.进程间通信 1.进程间通信--管道 (1)有名管道的创建 (2)有名管道的操作 写操作 读操作 发生阻塞和关闭程序的几种情况 2.无名管道的创建 (1)无名管道的操作 3.管道读取数据 ...
- 操作系统实验报告9:进程间通信—管道和 socket 通信
操作系统实验报告9 实验内容 实验内容:进程间通信-管道和 socket 通信. 编译运行课件 Lecture11 例程代码: alg.11-3-socket-input-2.c alg.11-4-s ...
- #Linux#进程间通信# 管道(pipe)-标准流管道pipe
在#Linux#进程间通信# 管道(pipe)-普通管道pipe中,我们很容易可以看出普通管道一是单工,即只能单向传输,而标准流管道针对匿名管道PIPE一系列封装.返回文件流.只不过返回的文件流无法使 ...
- linux学习:进程间通信—管道
1.进程间通信当中一种比較简单的方法是管道操作 /*========================================================================== ...
- Unix网络编程--进程间通信--管道通信
所有式样的Unix都提供管道,它由 pipe 函数创建,提供一个单路(单向)数据流. 原型如下: #include <unistd.h> int pipe(int ...
- [OS] 进程间通信--管道
管道是单向的.先进先出的.无结构的.固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起.写进程在管道的尾端写入数据,读进程在管道的首端读出数据.数据读出后将从管道中移走,其它读进 ...
- Linux进程间通信——管道
转自:http://www.cnblogs.com/feisky/archive/2010/03/24/1693484.html Linux进程间通信机制: 1.同一主机进程间通信机制: Unix方式 ...
- Linux进程间通信(管道、消息队列、共享内存、信号、信号量)
目录 Linux进程间通信概述 1.管道 无名管道(pipe) 有名管道(fifo) 2.消息队列(msg) 消息队列的通信原理 消息队列相关api 消息队列收发数据 键值生成 消息队列移除 3.共享 ...
- Linux系统【四】进程间通信-管道
进程间通信(IPC Interprocess Communication) 进程和进程之间的通信只能通过内核,在内核中提供一块缓冲区进行通信.内核提供的这种机制叫做IPC 在进程间完成数据传输需要借助 ...
- 进程间通信管道进阶篇:linux下dup/dup2函数的用法
由于利用管道实现进程间通信,是通过创建两个文件描述符,但是描述符的初始化是通过随机的,就是从可用的文件描述符中取出,并将可用的文件描述符与file对象相关联,如果我们需要将管道的两头与其他的流相关时, ...
最新文章
- vant组件实现上传图片裁剪_如何用 120 行代码,实现交互完整的拖拽上传组件?...
- CUDA学习3-GridBlock
- Bootstrap table表格
- 通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本...
- 用XFTP向Linux上传文件时出现Permission is not allowed
- 去除字符串中的html标记及标记中的内容
- Knative Serving 健康检查机制分析
- ios 设备获取idfa_超4成用户选择升级iOS 14,35%苹果设备已无法获取IDFA
- php中update语句修改多个字段,Myabtis中批量更新update多字段
- 扎哈遗作:北京大兴机场,耗资800亿,被英国《卫报》评为新世界七大奇迹!...
- 【CodeForces - 1102C 】Doors Breaking and Repairing (思维,简单博弈)
- 面向中文自然语言处理的60余类系统开源实践项目与工业探索索引
- php 调用日历控制,基于ThinkPHP实现的日历功能实例详解
- SQL SERVER 2000数据库置疑处理
- Java对接网易云信IM 即时通讯
- 【Python】一篇文章学习Pandas包 Pandas Series、DataFrame 对比学习
- 基于selenium的码市外包信息爬虫
- ios xmpp 发送语音图片解决方案
- android 高德地图sha1,Android调试高德SDK,如何获取SHA1?
- 删除Github中已有仓库或文件
热门文章
- 自然语言处理理论与实战
- Dynamics CRM2013 6.1.1.1143版本号插件注冊器的一个bug
- hadoop安装报错
- Struts2 工作流程
- (转)Android 如何建立你的菜单
- matlab指定的数据范围无效,c – 如何检查迭代器指定的范围是否有效?
- 大学计算机应用基础教程第三章,计算机应用基础教程 李健苹 计算机应用基础教程 第3章...
- json html双引号,当gethtml方法返回json时,json中的字符串如果存在双引号,会破坏json的格式, 如:quot;...
- Linux网络编程——tcp、udp迭代服务器
- ribbon基于接口配置超时_Spring Cloud第二篇:服务消费者RestTemplate+Ribbon