进程间的通信:管道

进程间的通信:管道

  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创建新进程,我们就可以通过管道在两个进程之间传递数据。

时间: 04-09

进程间的通信:管道的相关文章

linux 进程间的通信

现在linux使用的进程间通信方式:(1)管道(pipe)和有名管道(FIFO)(2)信号(signal)(3)消息队列(4)共享内存(5)信号量(6)套接字(socket) 为何进行进程间的通信:A.数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间B.共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到.C.通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程).D.资源共享

Linux进程间的通信

一.管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: A. 管道是半双工的,数据只能向一个方向流动: B. 需要双工通信时,需要建立起两个管道: C. 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): D. 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. 匿名管道的创建:该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义;因此,一

Linux/UNIX进程间的通信(1)

进程间的通信(1) 进程间的通信IPC(InterProcessCommunication )主要有以下不同形式: 半双工管道和FIFO:全双工管道和命名全双工管道:消息队列,信号量和共享存储:套接字和STREAMS 管道 pipe函数 当从一个进程连接到另一个进程时,我们使用术语管道.我们通常是把一个进程的输出通过管道连接到另一个进程的输入. 管道是由调用pipe函数创建的: #include<unistd.h> int pipe(intpipefd[2]); 经由参数pipefd返回两个文

进程间的通信

进程间通信概念:(IPC) 每个进程都有各自不同的进程地址空间,任何一个进程的全局变量在另一个进程中都看不到,因此进程之间要交换数据必须要通过内核,在内核中开辟一块缓冲区,进程把数据从用户空间拷贝到内核区,再从内核缓冲区取出数据.这就叫进程间的通信. 管道技术:(pipe) 是一种最基本进程间通信机制,它是基于字节流的.分为匿名管道和命名管道. 调用pipe函数时,会在内核区开辟一块缓冲区用于通信,它有一个读端和一个写端,通过参数传给用户程序两个文件描述符,0指管道的读端,1指管道的写端,因此管

Android 使用AIDL实现进程间的通信

在Android中,如果我们需要在不同进程间实现通信,就需要用到AIDL技术去完成. AIDL(android Interface Definition Language)是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作.关于AIDL的编写规则我在这里就不多介绍了,读者可以到网上查找一下相关资料. 接下来,我就演示一个操作AIDL的最基本的流程. 首先,我

进程间的通信如何实现

进程间的通信如何实现 版权声明:本文为博主原创文章,未经博主允许不得转载.

【转】使用AIDL实现进程间的通信之复杂类型传递

使用AIDL实现进程间的通信之复杂类型传递 首先要了解一下AIDL对Java类型的支持. 1.AIDL支持Java原始数据类型. 2.AIDL支持String和CharSequence. 3.AIDL支持传递其他AIDL接口,但你引用的每个AIDL接口都需要一个import语句,即使位于同一个包中. 4.AIDL支持传递实现了android.os.Parcelable接口的复杂类型,同样在引用这些类型时也需要import语句.(Parcelable接口告诉Android运行时在封送(marsha

Linux进程间的通信方法

linux进程间的通信方法总结如下 通过fork函数把打开文件的描述符传递给子进程 通过wait得到子进程的终结信息 通过加锁的方式,实现几个进行共享读写某个文件 进行间通过信号通信,SIGUSR1和SIGUSR2实现用户定义功能 利用pipe进行通信 FIFO文件进行通信 mmap,几个进程映射到同一内存区 SYS IPC 消息队列,信号量(很少用) UNIX Domain Socket,常用

进程间的通信简单总结

运行在不同的端系统的之间的通信: 进程指运行在端系统上的一个程序. 若要进行进程之间的通信,那么进程肯定就是成对出现的. 进程间的通信你可以想象是两个人用电话进行交流,然后它必须需要进行通信的一些基础设施,这个基础设施就是套接字,如果你在在两个进程之间进行数据交流,你可以把套接字想象成一个门,你打开门把你要传递的数据丢出去,然后另一个进程打开门,然后就收数据. 但是你把数据丢出门,它是如何找到目的地,另一个进程呢?数据报从一个进程找到另一个进程这就是进程寻址.你在打电话你需要提供电话号码,因此你