传递更多的数据
到目前为止我们所用的机制只是简单的在一个fread或是fwrite中发送或是接收全部的数据。有时我们也许以更小的尺寸发送数据,或是也许我们并不知道输出的大小。为了避免声明一个大的缓冲区,我们可以使用多个fread或是fwrite调用并分别处理这些数据。
下面是一个程序,popen3.c,由一个管道中读取所有的数据。
试验--由一个管道读取大量的数据
在这个程序中,我们由一个被调用的ps -alx进程读取数据。并没有办法预先知道会有多少输出,所以我们必须由管道中多次读取。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
FILE *read_fp;
char buffer[BUFSIZ +1];
int chars_read;
memset(buffer,'\0',sizeof(buffer));
read_fp = popen("ps -ax","r");
if(read_fp != NULL)
{
chars_read = fread(buffer,sizeof(char),BUFSIZ,read_fp);
while(chars_read > 0)
{
buffer[chars_read - 1] = '\0';
printf("Reading:-\n %s\n",buffer);
chars_read = fread(buffer,sizeof(char),BUFSIZ,read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
我们得到的输出结果如下:
$ ./popen3
Reading:-
PID TTY STAT TIME COMMAND
1 ? S 0:04 init
2 ? SW 0:00 [kflushd]
3 ? SW 0:00 [kpiod]
4 ? SW 0:00 [kswapd]
5 ? SW< 0:00 [mdrecoveryd]
...
240 tty2 S 0:02 emacs draft1.txt
Reading:-
368 tty1 S 0:00 ./popen3
369 tty1 R 0:00 ps -ax
...
工作原理
这个程序以与popen1.c相类似的方法使用"r"参数调用popen。但是这一次,程序会继续由文件流中读取数据,直到没有更多的数据。注意,尽管ps命令的执行需要一些时间,Linux会安排进程调度,从而在可能时两个程序同时运行。如果读进程,popen3,没有输入数据,他会挂起,直到有输入数据。如果写进程,ps,产生了更多的可缓冲的数据,他就会挂起,直到读进程消化掉其中的一些数据。
popen是如何实现的
popen调用通过首先调用shell,sh,将command字符串作为参数传递给他来运行我们所请求的程序。这有两个效果,一个是好的,而另一个并不是这样好。
在Linux(同时在所有的类Unix系统)中,所有的参数扩展都是通过shell来完成的,所以在程序被调用之前调用shell来分析命令字符串会允许在程序启动之前完成任意的shell扩展,例如,确定'*.c'实际指向哪些文件。这通常是非常有用的,而且这允许使用popen来启动复杂的shell命令。其他的进程创建函数,例如execl,其调用可以更为复杂,因调用进程必须执行其自己的shell扩展。
使用shell的另一个效果就是对于每一个popen调用,必须为所请求的程序调用一个shell。从而每一个popen调用就会另外两个额外进程,这就会使得popen函数就系统资源而言更为昂贵,而且目标命令的调用速度更慢。
下面是程序popen4.c,我们可以模拟popen的行为。我们通过cat文件来计算所有popen例子源程序的行数,然后通过管道输出给wc -l,后者会计算这些行数。在命令行,等同的命令如下:
$ cat popen*.c | wc -l
实际上,wc -l poen*.c命令输入更为简单而且更为高效,但是这个例子是为了演示这些原则。
试验--popen启动一个Shell
这个程序实际上使用前面的命令,但是通过popen可以读取结果:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
FILE *read_fp;
char buffer[BUFSIZ +1];
int chars_read;
memset(buffer,'\0',sizeof(buffer));
read_fp = popen("cat popen*.c | wc -l","r");
if(read_fp != NULL)
{
chars_read = fread(buffer,sizeof(char),BUFSIZ,read_fp);
while(chars_read > 0)
{
buffer[chars_read -1] = '\0';
printf("Reading:-\n %s\n",buffer);
chars_read = fread(buffer,sizeof(char),BUFSIZ,read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
当我们运行这个程序,我们会得到下面的输出:
Reading:-
98
工作原理
这个程序证明了被调用的shell将popen*.c扩展为所有以popen开头并以.c结束的文件列表,同时处理管道符号,并将cat的输入传递给wc。我们在一个popen调用中调用shell,cat程序以及wc程序,并将结果重定向。调用命令的程序只看到最终的结果。
分享到:
相关推荐
#### 二、进程间通信与同步的区别与联系 进程间通信与同步虽然密切相关,但在不同的操作系统中实现方式存在差异。在Linux这样的虚拟内存系统中,每个进程都有自己的地址空间,因此进程间通信是通过专门的机制来实现...
七种进程间通信方式: 一.无名管道( pipe ) 二.有名管道( fifo ) 三.共享内存 ( shared memory ) 四.信号 ( sinal ) 五.消息队列 ( message queue ) 六.信号量 ( semophore ) 七.套接字 ( socket ) 进程间通信...
UNIX网络编程第二卷 进程间通信
在IT领域,进程间通信(IPC,Inter-Process Communication)是一项关键的技术,它允许不同的进程之间交换信息,协同工作。本示例以“C#与C++进程间通信”为主题,利用命名管道(Named Pipe)作为通信媒介,实现了...
《UNIX网络编程 第2版 第2卷 进程间通信》是UNIX系统下进行网络编程不可或缺的经典著作,尤其在深入理解和实践进程间通信(IPC,Inter-Process Communication)方面提供了丰富的知识和技术指导。本书详细阐述了如何...
UNIX网络编程_卷2_进程间通信第二版.pdf,绝对高清,绝对正版,不用积分下载
进程间通信之信号 sinal ) 唯一的异步通信方式 七种进程间通信方式: 一 无名管道( pipe ) 二 有名管道( fifo ) 三 共享内存 shared memory 四 信号 sinal 五 消息队列 message queue ) 六 信号量 ...
笔记_UNIX环境网络编程卷二进程间通信_中文第二版
共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。...1、进程间通信 2、共享内存 3、托管方式与非托管共享内存
在Linux操作系统中,进程间通信(IPC,Inter-Process Communication)是多个进程之间共享数据、交换信息的一种机制。它是多任务环境下实现协作和同步的重要手段。Linux提供了多种进程间通信方式,包括管道(Pipe)、...
UNIX进程间通信(第二版)可能详细探讨了以下知识点: 1. **信号(Signals)**:UNIX系统中最早实现的进程间通信方式之一,用于发送异步事件通知。信号可以用来中断进程、改变进程状态或执行用户指定的操作。 2. *...
《UNIX进程间通信(第二版)》是一本深入探讨UNIX操作系统中进程间通信(IPC,Inter-Process Communication)的专业书籍。这本书涵盖了从基础概念到高级技术的全面内容,旨在帮助读者理解和掌握在UNIX环境中实现不同...
操作系统实验报告(LINUX进程间通信) 操作系统实验报告(LINUX进程间通信)是操作系统课程的一部分,涵盖了Linux进程间通信的原理和应用,包括消息队列、C/S结构等内容。下面将对这些知识点进行详细的解释。 一、...
UNIX网络编程----进程间通信----卷2【第二版】源码
### Linux 进程间通信详解 #### 一、管道及有名管道 在深入探讨Linux中的进程间通信(IPC)机制之前,我们先了解一个基本概念:**进程**。进程是程序执行的一个实例,每个进程都有自己的地址空间。当多个进程需要...
进程间通信之套接字( socket ) 网络间通信 七种进程间通信方式: 一.无名管道( pipe ) 二.有名管道( fifo ) 三.共享内存 ( shared memory ) 四.信号 ( sinal ) 五.消息队列 ( message queue ) 六.信号量 ( ...
#### 二、进程间通信的基本概念 进程间通信是指不同进程之间互相交换信息的过程。在Linux环境下,进程间通信不仅限于同一台计算机上的进程通信,也可以跨网络进行。进程间通信机制的设计目的是为了提高程序的模块化...
在编程领域,进程间通信(IPC,Inter-Process Communication)是一项关键的技术,它允许不同的进程之间交换数据,协同工作。Delphi,作为一个强大的面向对象的编程环境,提供了多种方式进行进程间通信。本篇文章将...
《UNIX进程间通信(第二版)》这本书可能详细讲解了这些概念,并通过实例深入探讨了它们的使用方法和最佳实践。书中可能涵盖如何创建和管理这些通信机制,以及如何解决可能出现的并发控制和同步问题。通过学习这本书...
Linux进程间通信(IPC)是操作系统中非常重要的部分,它包括多种机制用于进程间的数据交换。了解这些机制对于进行系统编程和软件开发非常重要。本文档详细介绍了管道、信号、消息队列、信号量和共享内存等通信方法。...