pipe(管道)

  • 专用于父子进程通信, 函数原型 int pipe(int fd[2])
  • fd[0]表示输入, fd[1]表示输出
  • 如果父子进程要双向通信, 可以通过类似信号的功能进行控制, 也可以简单地打开两个pipe

以下例子, 打开两个pipe, 第一个pipe用于父进程向子进程发送信息, 第二个pipe用于子进程向父进程发送消息

子进程接收到消息后, 将消息转成大写然后发送给父进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h> char *strupr(char *str){
char *orign=str;
for(;*str != 0;++str)
*str=toupper(*str);
return orign;
}
void err_quit(const char *str){
perror(str);
exit(1);
}
int main(){
int n;
int fd1[2], fd2[2];
pid_t pid;
char line[1024]; if(pipe(fd1)<0 || pipe(fd2)<0)
err_quit("pipe error"); if((pid =fork())<0){
err_quit("pipe error");
}else if(pid >0 ){
close(fd1[0]);
close(fd2[1]);
write(fd1[1],"hello world\n",12);
n=read(fd2[0],line,1024);
write(STDOUT_FILENO,line,n);
}else{
close(fd1[1]);
close(fd2[0]);
n=read(fd1[0],line,1024);
write(STDOUT_FILENO,line,n);
line[n]='\0';
write(fd2[1],strupr(line),n);
}
exit(0);
}

popen和pclose

  • 函数原型FILE *popen(const char *cmdstring, const char *type) , type的参数为"r"或"w"
  • 用于父子进程通信, popen会自动fork子进程、创建pipe和关闭不需要的pipe端
  • popen的实现有可理解为execl("/bin/sh","sh","-c",cmdstring,NULL)
  • 当父进程向子进程发送信息时(type="w"), 实际就是向shell发送命令;

    当父进程从子进程获取信息时(type="r"), 实际就是读取shell的执行结果
  • 虽然popen的返回是FILE,但关闭是要用pclose(fp)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> #define MAXLINE 1024
void err_quit(const char *str){
perror(str);
exit(1);
}
int main(){
char line[MAXLINE];
FILE *fpin; if((fpin=popen("ls -l","r")) == NULL)
err_quit("popen error");
while(fgets(line,MAXLINE,fpin) != NULL){
if(fputs(line,stdout) ==EOF)
err_quit("fputs error");
}
if(ferror(fpin))
err_quit("fpin error");
if(pclose(fpin)==-1)
err_quit("pclose error");
return 0;
}

fifo

  • int mkfifo(const char *pathname,mode_t mode), 创建一个通信文件, 参数同open
  • mkfifo后, 以open打开文件, 打开方式为只读或只写, 另外可以非阻塞方式打开
  • 以只读打开时, 函数会阻塞直到有进程以只写方式打开
  • 以只写打开时, 函数会阻塞直到有进程以只读方式打开
  • 可用于非父子进程通信, 双向通信时开需两个
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h> #define FILE_MODE S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IROTH
void err_quit(const char *str){
perror(str);
exit(1);
}
int main(){
char *pathname="./fifobuf";
pid_t pid; if(mkfifo(pathname,FILE_MODE)<0)
err_quit("mkfifo error"); if((pid=fork())<0){
err_quit("fork error");
}else if(pid >0){
int fd;
if((fd=open(pathname,O_RDONLY))<0)
err_quit("open error");
char buf[100];
int n;
if((n=read(fd,buf,100)) < 0)
err_quit("read error");
buf[n]=0;
puts(buf);
exit(0);
}else{
int fd;
if((fd=open(pathname,O_WRONLY))<0)
err_quit("open error");
char *str="hello world";
write(fd,str,strlen(str));
exit(0);
}

pipe/popen/fifo的更多相关文章

  1. 信号处理篇alarm ferror kill mkfifo pause pclose perror pipe popen sigaction sigaddset sigdelset sigemptyset signal sleep strerror

    alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...

  2. 进程间通信和同步:pipe、FIFO、消息队列、信号量、共享内存、信号

    一.半双工管道(pipe) 关于管道详细介绍可参考http://www.cnblogs.com/nufangrensheng/p/3560130.html. 1.管道实现父子进程间通信实例: /* p ...

  3. 进程间通信之管道(pipe、fifo)

    我们先来说说进程间通信(IPC)的一般目的,大概有数据传输.共享数据.通知事件.资源共享和进程控制等.但是我们知道,对于每一个进程来说这个进程看到属于它的一块内存资源,这块资源是它所独占的,所以进程之 ...

  4. 进程间通信之管道--pipe和fifo使用

    匿名管道pipe 函数原型: #include <unistd.h> int pipe(int fildes[2]); 参数说明 fildes是我们传入的数组,也是一个传出参数.filde ...

  5. 【Linux 应用编程】进程管理 - 进程间通信IPC之管道 pipe 和 FIFO

    IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...

  6. linux多进/线程编程(4)——进程间通信之pipe和fifo

    前言: Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间.任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块 ...

  7. Linux中的pipe(管道)与named pipe(FIFO 命名管道)

    catalogue . pipe匿名管道 . named pipe(FIFO)有名管道 1. pipe匿名管道 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常 ...

  8. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  9. 进程间通信IPC之--无名管道(pipe)和有名管道(fifo)(转)

     进程间通信IPC之--无名管道(pipe)和有名管道(fifo) 2012-01-17 22:41:20 分类: C/C++ 每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中 ...

随机推荐

  1. VMware系统运维(九)VMware vSphere Client 安装

    1.点击下一步 2.接受协议,下一步 3.选择安装位置,下一步 4.开始安装 5.安装完成,进行登录测试. VMware vsphere 5.1 登录名为administrator    VMware ...

  2. 获取数组排序后的index算法实现

    需求: 一个数组var arr = [4,7,2,9],排序后的新数组var newArr = [2,4,7,9]或者[9,7,4,2] 我们要得到的是排序后元数组的每一项在新数组中的位置所构成的数组 ...

  3. hdu 2489 最小生成树状态压缩枚举

    思路: 直接状态压缩暴力枚举 #include<iostream> #include<algorithm> #include<cstdio> #include< ...

  4. oledb,odbc简易实体生成器.

    DataSet to code file(C#)工具. 方便自己写的odbc或者oledb的东西用的. sql server或者oracle等大数据库已经有EF的支持. 一些其他数据库还是用oledb ...

  5. iOS 简单block的使用

    1.第一种方法 声明block: - (void)test:(int) param_1 completion:(void(^)(int)) completion; 实现block: -(void)te ...

  6. excel上传与下载

    后台:        @RequestMapping(value = "/uploadFile.do", method = RequestMethod.POST)  public ...

  7. QA在网站建设中的作用

    在网站建设项目中,有一个团队负责产品测试并识别产品中的缺陷是很有意义的.问题在于,不应该只依赖这个团队来发现所有的缺陷,就像航空公司不能只依靠空乘人员确保飞机安全一样.这个观点的核心是一个简单的事实, ...

  8. 怎样把function中的arguments变成普通数组

    当我们在写一个具有处理可变长度参数的函数时,需要对arguments做一些操作.但是arguments它并不是一个数组,没有数组的各种操作,而且,JS的严格模式中不允许更改它的值. 这时我们需要将它的 ...

  9. ThinkPHP中的模型二

    ThinkPHP中的模型 1.为什么要创建数据对象 案例:使用ThinkPHP完成部门管理 ① 设计数据库 ② 创建Dept控制器 路径:./Application/Admin/Controller创 ...

  10. Struts2+Hibernate4+Spring4整合

    jar包 配置文件 web.xml文件 <!-- needed for ContextLoaderListener --> <context-param> <param- ...