并发控制3:进程通信之popen,pclose
popen和pclose调用后实现的操作是:创建一个管道,fork一个子进程,关闭未使用的管道端,在子进程执行shell命令。函数原型如下:
#include <stdio.h> FILE* popen(const char* cmdstring,const char* type) cmdstring:shell命令 type: "r":父进程读取管道,子进程写管道 “w":父进程写管道,子进程读管道
int pclose(FILE* stream)
执行popen之后,实际上有两个进程,进程间通过管道通信,子进程执行的程序为execl("/bin/sh","sh","-c",cmdstring,NULL),如下图所示:
* type类型为"r" * type类型为"w"
比如我们要查看当前目录下的所有txt文档, 命令为shell命令为"ls *.txt",程序如下:
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <stdlib.h> //为了简便,没有考虑错误处理 int main() { char line[50]; FILE* fp=popen("ls *.txt","r"); while(fgets(line,50,fp)!=NULL) printf("From fp:%s\n",line); pclose(fp); exit(0); }
在并发控制1:进程通信之管道的1小节后面,有一个程序:父进程读取txt文档,通过管道发送到子进程,子进程调用分页程序显示。整个过程与popen执行的流程类似,现用popen重写程序:
//头文件与上面代码一致 #define PAGER "${PAGER:-more}" #define MAX_LEN 50 //为了简便,没考虑错误控制 int main() { char line[MAX_LEN]; FILE* fin=fopen("pipe.txt","r"); FILE* fout=popen(PAGER,"w"); while(fgets(line,MAX_LEN,fin)!=NULL) { fputs(line,fout); } pclose(fout); fclose(fin); exit(0); }