博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程间通信的方式简单解析————管道
阅读量:4166 次
发布时间:2019-05-26

本文共 3613 字,大约阅读时间需要 12 分钟。

本人最近学习了进程间通信,并看了一些博文,然后结合书籍根据自己的理解写了这篇文章。

1. 管道

函数原型:经由参数fd返回两个文件描述符:fd[0]为读,fd[1]为写。fd[1]的输出是fd[0]的输入。

#include 
int pipe(int fd[2]);

局限性:

(1)历史上,它是半双工的,某些系统提供全双工管道,即其可移植性并不好。
(2)它只能在具有公共祖先的两个进程间使用。

示例代码:

#include 
#include
#include
#include
int main(){
int pipe_fd[2]; int ret = pipe(pipe_fd);//类似两个文件指针,针对管道中的读(0)和写(1) if(ret == -1) {
printf("创建管道失败,错误码是:%d,%d\n",error,strerror(error)); return 0; } pid_t pid = fork();//创建子进程 if(pid < 0) {
printf("创建子进程错误\n"); return 0; }else if(pid == 0) {
//子进程的操作 close(_pipe[0]); // 关闭读通道 int i = 0; char sendbuf[BUFSIZ]; while( i < 20){
scanf("%s", sendbuf); write(pipe_fd[1], sendbuf, strlen(sendbuf)); sleep(2); i++; } }else {
//进入父进程,从子进程读取数据 close(pipe_fd[1]); //关闭写通道 char recv[BUFSIZ]; while(1){
memset(recv, 0, sizeof(recv)); int length= read(pipe_fd[0], recv, sizeof(recv)); if(strstr(recv, "quit") != 0) {
printf("退出程序\n"); exit(0); } printf("message:%s. length:%d.\n", recv, length); } if(waitpid(pid, NULL, 0) < 0) {
//避免父进程与子进程冲突,让子进程先执行 return 0; } } return 0;}

运行结果:

在这里插入图片描述

2. 命名管道(FIFO)

函数原型:

#include
int mkfifo(const char *path, mode_t mode); int mkfifoat(int fd, const char *path, mode_t mode);

参数信息:

(1)参数fd为文件描述符。
(2)参数path为路径名。
(3)mode参数指定文件的访问权限位。

FIFO的用途:

(1)shell命令使用FIFO将数据从一条管道传送到另一条时,无需创建中间临时文件。
(2)C/S应用程序中,FIFO用作汇聚点,在二者之间传递数据。

示例代码:fifo-read.c

#include 
#include
#include
#include
#include
#include
#define _PATH_ "/tmp/file.fifo"int main(){ int fd = open(_PATH_, O_RDONLY);//以只读的权限打开文件 if(fd < 0){ printf("打开失败\n"); return 0; } char recv[BUFSIZ]; while(1){ memset(recv, 0, sizeof(recv));//字符串清零 int ret = read(fd, recv, sizeof(recv)); if(strstr(recv, "quit") != 0){ //判断接收到的字符是否是quit printf("退出程序\n"); exit(0); } printf("message:%-20s. length:%d\n", recv, ret); } close(fd);//关闭文件 return 0;}

运行结果:

在这里插入图片描述

fifo-write,c

#include 
#include
#include
#include
#include
#include
#include
#define _PATH_ "/tmp/file.fifo"int main(){ int ret = mkfifo(_PATH_, 0666);//创建管道文件 if(ret == -1){ printf("创建管道失败\n"); exit(0); } int fd = open(_PATH_, O_WRONLY);//以只写的权限打开文件 if(fd < 0){ printf("打开失败\n"); exit(0); } char buf[BUFSIZ]; while(1){ memset(buf, 0, strlen(buf));//字符串清零 printf("please input the string:"); scanf("%s", buf); int ret = write(fd, buf, strlen(buf));//写数据 if(ret < 0){ printf("写出错\n"); break; } if(strstr(buf, "quit") != 0){ break; } } close(fd);//关闭文件 unlink(_PATH_);//删除管道文件 return 0;}

运行结果:

在这里插入图片描述

你可能感兴趣的文章
HTML5学习之——HTML 5 Canvas vs. SVG
查看>>
HTML5学习之——HTML 5 应用程序缓存
查看>>
HTML5学习之——HTML 5 Web Workers
查看>>
HTML5学习之——HTML 5 Canvas
查看>>
HTML5学习之——HTML5 内联 SVG
查看>>
HTML5学习之——HTML 5 服务器发送事件
查看>>
SVG学习之——HTML 页面中的 SVG
查看>>
SVG 形状学习之——SVG圆形
查看>>
SVG 滤镜学习之——SVG 滤镜
查看>>
mysql中用命令行复制表结构的方法
查看>>
hbase shell出现ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException
查看>>
让代码变得更优雅-Lombok
查看>>
解决Rhythmbox乱码
查看>>
豆瓣爱问共享资料插件发布啦
查看>>
Ubuntu10.10 CAJView安装 读取nh\kdh\caj文件 成功
查看>>
kermit的安装和配置
查看>>
vim 配置
查看>>
openocd zylin
查看>>
进程创建时文件系统处理
查看>>
内核线程创建
查看>>