在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值。这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据。
一、什么是管道
如果你使用过Linux的命令,那么对于管道这个名词你一定不会感觉到陌生,因为我们通常通过符号“|"来使用管道,但是管理的真正定义是什么呢?管道是一个进程连接数据流到另一个进程的通道,它通常是用作把一个进程的输出通过管道连接到另一个进程的输入。
举个例子,在shell中输入命令:ls -l | grep string,我们知道ls命令(其实也是一个进程)会把当前目录中的文件都列出来,但是它不会直接输出,而是把本来要输出到屏幕上的数据通过管道输出到grep这个进程中,作为grep这个进程的输入,然后这个进程对输入的信息进行筛选,把存在string的信息的字符串(以行为单位)打印在屏幕上。
二、使用popen函数
1、popen函数和pclose函数介绍
有静就有动,有开就有关,与此相同,与popen函数相对应的函数是pclose函数,它们的原型如下:
#include <stdio.h> FILE* popen (const char *command, const char *open_mode); int pclose(FILE *stream_to_close);
poen函数允许一个程序将另一个程序作为新进程来启动,并可以传递数据给它或者通过它接收数据。command是要运行的程序名和相应的参数。open_mode只能是"r(只读)"和"w(只写)"的其中之一。注意,popen函数的返回值是一个FILE类型的指针,而Linux把一切都视为文件,也就是说我们可以使用stdio I/O库中的文件处理函数来对其进行操作。
如果open_mode是"r",主调用程序就可以使用被调用程序的输出,通过函数返回的FILE指针,就可以能过stdio函数(如fread)来读取程序的输出;如果open_mode是"w",主调用程序就可以向被调用程序发送数据,即通过stdio函数(如fwrite)向被调用程序写数据,而被调用程序就可以在自己的标准输入中读取这些数据。
pclose函数用于关闭由popen创建出的关联文件流。pclose只在popen启动的进程结束后才返回,如果调用pclose时被调用进程仍在运行,pclose调用将等待该进程结束。它返回关闭的文件流所在进程的退出码。
2、例子
很多时候,我们根本就不知道输出数据的长度,为了避免定义一个非常大的数组作为缓冲区,我们可以以块的方式来发送数据,一次读取一个块的数据并发送一个块的数据,直到把所有的数据都发送完。下面的例子就是采用这种方式的数据读取和发送方式。源文件名为popen.c,代码如下:
#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); }
运行结果如下:
从运行结果来看,达到了信息筛选的目的。程序在进程ls中读取数据,再把数据发送到进程grep中进行筛选处理,相当于在shell中直接输入命令:ls -l | grep rwxrwxr-x。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 函数
, 程序
, 进程
, 匿名管道 readfile
, popen php 管道
, 管道
, cannot poen file
, 匿名管道
, popen
, 二进制流读取 fread
, 一个
, 管道符号
管道输入函数
,以便于您获取更多的相关知识。