进程间的通信:管道

来源:互联网 发布:linux 静态ip连接外网 编辑:程序博客网 时间:2024/04/30 13:39

进程间的通信:管道

  Linux中将命令联系到一起使用实际上就是把一个进程的输出通过管道传递给另一个进程的输入,这些都是shell封装好的,对标准输入和输出流进行了重新连接,使数据流从键盘输入经过两个程序最终输出到屏幕上。如下:

cmd1|cmd2

进程管道

  在两个程序之间传递数据最简单的方法就是使用popen()和pclose()了。原型如下:

#include <stdio.h>FILE *popen(const char *command, const char *open_mode);int pclose(FILE *stream_to_close);

1.popen函数

  popen函数允许一个程序将另一个程序作为新程序来启动。并可以传递数据给他或者通过它接收数据。command是要运行的程序名和参数,open_mode是调用程序的方式,必须是”r”或”w”。
  请求popen调用运行一个程序时,它首先启动shell,然后将command字符串作为一个参数传递给它。在启动程序之前就先启动shell分析命令字符串,这样可以允许程序很方便的启动很复杂的shell命令。但是每一个popen调用不但会启动被请求的程序还要启动一个shell,这样导致了系统资源的浪费,所以popen函数调用目标命令要比正常方式慢一些。
  popen会返回一个文件流指针。根据文件流指针可以与新程序进行相应的读写操作。
  如果以读方式打开,可以通过stdio的库函数fread来读取被调用程序的输出。fread会从stream流中读取count个,每个大小为size字节的数据,并写入到buffer中。然后返回实际读取的元素个数,如果返回值与count不相同,则可能文件结尾或发生错误。
  如果是以写的方式打开,可以使用fwrite函数向被调用程序中写入数据。
  这里文件的读写可以使用fread和fwrite,但不局限于这两个函数。fgets和fputs等等也是完全可以的。

#include <stdio.h>size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

2.pclose函数

  pclose函数用于关闭由popen建立的管道和文件指针。pclose只在popen启动的进程结束之后才返回,如果调用pclose时程序还在运行,pclose会等待程序结束。

底层的管道函数pipe

#include <unistd.h>int pipe(int file_descriptor[2]);

  通过这个函数在两个程序之间传递数据不再需要启动一个shell来解释请求的命令,同时它还提供了对读写更多的控制。pipe函数的参数是一个由两个整数类型的文件描述符组成的数组指针,pipe在数组中填上两个新的文件描述符后返回0。写到file_descriptor[1]中的数据都可以从file_descriptor[2]中读取出来,读取数据采用FIFO的原则。
  注:由于这里使用的是文件描述符而不是文件流,所以我们要使用底层的read和write函数来进行读写而不是文件流库函数fread和fwrite。

管道的真正优势体现在两个进程之间传递数据的时候,当程序用fork调用创建新进程时,原先打开的文件描述符仍将保持打开状态。如果在原先的进程中创建一个管道,然后再调用fork创建新进程,我们就可以通过管道在两个进程之间传递数据。

0 0
原创粉丝点击