学科分类
目录
Linux编程

popen()/pclose()

管道通信的一般流程是:在一个进程中创建管道,通过fork()创建子进程,关闭管道多余端口,使父子进程与管道形成单向通道,进行数据传输。Linux标准I/O库中封装了两个函数——popen()和pclose(),使用这两个函数即可完成管道通信的流程。

popen()和pclose()函数存在于函数库stdio.h中,它们的函数声明分别如下:

FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

popen()函数的功能是:调用pipe()函数创建管道,调用fork()函数创建子进程,之后在子进程中通过execve()函数调用shell命令执行相应功能,若整个流程都成功执行,则返回一个I/O文件指针;若pipe()或fork()函数调用失败,或因无法分配内存等原因造成popen()函数调用失败,该函数将会返回NULL。

popen()函数的参数command用来传入要执行的shell命令;type用于指定命令类型(输入w/输出r),因为管道是单向的,所以type参数只能设定为读取或者写入:若type设定为“r”,文件指针连接到command的标准输出,返回的文件指针是可读的;若type设定为“w”,文件指针连接到command的标准输入,返回的文件指针是可写的。父进程与由popen()创建出的进程之间的关系如图1所示。

图1 popen()调用结果

pclose()函数的功能是关闭由popen()打开的I/O流,并通过调用wait()函数等待子进程命令执行结束,返回shell的终止状态,防止产生僵尸进程。与文件操作函数fopen()类似, popen()调用之后务必要使用pclose()函数关闭打开的文件I/O指针,若pclose()函数调用失败,则返回-1。

下面通过案例来展示popen()函数与pclose()函数的使用方法。

案例3:使用popen()函数与pclose()函数实现管道通信。

 1    #include <stdio.h>
 2    #include <stdlib.h>
 3    #include <unistd.h>
 4    int main()
 5    {
 6        FILE *r_fp,*w_fp;
 7        char buf[100];
 8        r_fp=popen("ls","r");               //读取命令执行结果
 9        w_fp=popen("wc -l","w");            //将管道中的数据传递给进程
 10        while(fgets(buf,sizeof(buf),r_fp)!=NULL)
 11            fputs(buf,w_fp);
 12        pclose(r_fp);
 13        pclose(w_fp);
 14        return 0;
 15    }

编译案例,执行程序,执行结果如下所示:

101

其中101为兄弟进程对“ls | wc -l”命令的实现结果,在终端输入该命令,得到的结果与程序相同,可知案例成功实现。popen()函数和pclose()函数实现的代码要更加简洁。

点击此处
隐藏目录