`
mylxiaoyi
  • 浏览: 327508 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

进程间通信(一)

阅读更多

第13章 进程间通信:管道

在第11章,我们了解了使用信号在两个进程之间发送消息的一个简单方法。我们创建了可以用来引起响应的通知事件,但是所传递的信息限制于一个信号数量。

在这一章,我们将会了解管道,这会允许在进程之间交换更为有用的数据。在本章的结尾,我们将会使用我们的新知识来重新将CD数据库程序实现为一个非常简单的客户/服务器程序。

在本章,我们将会涉及下列主题:

管道的定义
处理管道
管道调用
父子进程
有名管道:FIFO
客户端/服务器方法

什么是管道?

当我们由一个进程到另一个进程连接数据流时我们使用术语管道。通常我们将一个进程的输出连接到另一个进程的输入。

大多数Linu用户已经很熟悉将shell命令连接到一起的思想,从而一个进程的输入可以直接连接到另一个进程的输入。对于shell命令,这是用下面的方式来输入的:

cmd1 | cmd2

shell安排标准输入与两个命令的输出,从而
cmd1的标准输入来自由终端键盘
cmd1的标准输出作为标准输入连接cmd2
cmd2的标准输出连接到终端屏幕

实际上,shell所完成的工作就是重新连接标准输入与输出流,从而由键盘输入的数据流可以通过两个命令,然后输出到屏幕。下图是这个过程的一个可视化表示。

在这一章,我们将会了解如何在一个程序中实现这种效果,以及我们如何使用管道来连接多个进程从而使得我们实现一个简单的客户端/服务器系统。

处理管道

也许在两个程序之间传递数据最简单的方法就是使用popen与pclose函数了。这两个函数原型如下:

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

popen

popen函数允许一个程序调用另一个程序作为一个新的进程,并且或者向其发送数据或者由其接收数据。command字符串是要运行的程序名字及其参数。open_mode必须或者是"r"或者是"w"。

如果open_mode是"r",由被调用程序的输出可以为调用程序所用,并且可以使用通常的stdio库函数中用于读取的函数由popen函数所返回的文件流 FILE *中进行读取。然而,如果open_mode是"w",程序可以使用fwrite调用向被调用的程序发送数据。被调用的程序可以由其标准输入读取数据。通常,正被调用的程序并不会知道他正在由另一个进程读取数据;他只是简单的读取其标准输入流。

popen调用必须指明是"r"或者是"w";在popen的标准实现中并不支持其他的选项。这就意味着我们不能调用另一个程序,同时由其读取并向其写入。一旦失败,popen就会返回一个空指针。如果我们希望使用管道进行双向通信,通常的解决方法是使用两个管道,每个方向用于一个数据流。

pclose

当由popen所启动的进程已经完成时,我们可以使用pclose来关闭与其相关的文件流。pclose调用只会在由popen所启动的进程完成时才会返回。如果当调用pclose时,这个进程仍在运行,pclose调用就会等待这个进程结束。

pclose调用通常返回他正关闭的进程的文件流的返回的代码。如果调用在调用pclose之前已经执行了一个wait语句,返回状态就会丢失,而pclose就会返回-1,并且将errno设置为ECHILD。

试验--读取另一个程序的输出

下面我们来试验一个简单的popen与pclose的例子,popen1.c。我们会在一个程序中使用popen来访问uname所输出的信息。uname -a命令输出系统信息,包括机器类型,OS名字,版本号以及机器的网络名。

在初始化程序之后,我们打开一个连接uname的管道,使其可读并且设置read_fp指向输出。最后,由read_fp指向的管道会被关闭。

#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("uname -a","r");
if(read_fp != NULL)
{
chars_read = fread(buffer,sizeof(char),BUFSIZ,read_fp);
if(chars_read > 0)
{
printf("Output was:-\n%s\n",buffer);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}

当我们运行这个程序,我们就会得到下面的输出:

$ ./popen1
Output was:-
Linux gw1 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux

工作原理

这个程序使用popen调用来调用带有-a参数的uname命令。他然后使用所返回的文件流来读取直到BUFSIZ个字符然后输出到屏幕上。因为我们在一个程序内部捕获uname输出的,所以他可以用来处理。

向popen发送输出

现在我们已经看到由一个外部程序捕获输出的例子,下面我们来看一下向另一个程序发送输出。这就是popen2.c,将数据导向另一个管道。在这里我们将使用od(octal dump)。

试验--向外部程序发送输出

看一下下面的代码,如果我们愿意可以将其输入文本编辑器。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
FILE *write_fp;
char buffer[BUFSIZ +1];

sprintf(buffer,"Once upon a time, there was...\n");
write_fp = popen("od -c","w");
if(write_fp != NULL)
{
fwrite(buffer,sizeof(char),strlen(buffer),write_fp);
pclose(write_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}

当我们运行这个程序时,我们会得到下面的输出:

$ ./popen2
0000000 O n c e u p o n a t i m e
0000020 , t h e r e w a s . . . \n
0000037

工作原理

这个程序使用带有"w"参数的popen调用来启动od -c命令,从而他可以向这个命令发送数据。然后他发送一个字符串,od -c命令可以接收并处理;od -c命令然后在其标准输出上输出其处理结果。

在命令行上,我们可以使用下面的命令来得到同样的结果

$ echo “Once upon a time, there was...” | od -c

分享到:
评论

相关推荐

    linux进程间通信与同步.pdf

    - **共享内存(Shared Memory)**:共享内存是最有效的进程间通信方法之一,它允许多个进程共享一块内存区域,从而实现数据的高效交换。 ##### Linux系统中的同步机制 在Linux系统中,由于多个进程共享内核空间,...

    进程间通信

    七种进程间通信方式: 一.无名管道( pipe ) 二.有名管道( fifo ) 三.共享内存 ( shared memory ) 四.信号 ( sinal ) 五.消息队列 ( message queue ) 六.信号量 ( semophore ) 七.套接字 ( socket ) 进程间通信...

    C#与C++进程间通信

    在IT领域,进程间通信(IPC,Inter-Process Communication)是一项关键的技术,它允许不同的进程之间交换信息,协同工作。本示例以“C#与C++进程间通信”为主题,利用命名管道(Named Pipe)作为通信媒介,实现了...

    进程间通信源码

    进程间通信(IPC,Inter-Process Communication)是操作系统中一种重要的技术,允许不同进程之间交换数据和协调工作。在多任务环境下,进程间通信对于实现并发执行、资源共享和协同工作至关重要。本文将深入探讨进程...

    linux 操作系统进程间通信 ppt

    进程间通信是操作系统中非常重要的一部分,涉及到进程之间的信息交换、同步和互斥等问题。 在 Linux 操作系统中,进程间通信可以分为两类:低级通信和高级通信。低级通信是指控制信息的传递,例如进程之间的同步和...

    跨平台进程间通信源码

    跨平台进程间通信(IPC,Inter-Process Communication)是计算机技术中的一个重要概念,它允许不同进程之间共享数据、协调工作,实现系统资源的有效利用。在标题中提到的“跨平台进程间通信源码”可能是一个软件库...

    进程间通信例子

    进程间通信(Inter-Process Communication, IPC)是操作系统中一种重要的技术,允许不同进程之间交换数据和信息。在Windows环境中,实现进程间通信有多种方式,包括但不限于管道、消息队列、共享内存、套接字、命名...

    进程间通信--操作系统实验

    在操作系统领域,进程间通信(IPC,Inter-Process Communication)是一项至关重要的技术,它使得不同进程之间能够交换数据,协同工作。本实验“进程间通信--操作系统实验”旨在帮助学生深入理解和熟练掌握这一核心...

    进程间通信之信号 sinal ) 完整代码

    进程间通信之信号 sinal ) 唯一的异步通信方式 七种进程间通信方式: 一 无名管道( pipe ) 二 有名管道( fifo ) 三 共享内存 shared memory 四 信号 sinal 五 消息队列 message queue ) 六 信号量 ...

    UNIX网络编程 第2版 第2卷 进程间通信

    总之,《UNIX网络编程 第2版 第2卷 进程间通信》是一本全面覆盖UNIX系统下进程间通信的宝典,无论你是初学者还是经验丰富的开发者,都能从中受益匪浅,提升你的网络编程技能。结合书中的实例和实践,你将能更好地...

    C# 进程间通信 共享内存

    共享内存,顾名思义就是允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。...1、进程间通信 2、共享内存 3、托管方式与非托管共享内存

    Linux进程间通信.pdf

    进程间通信是Linux系统中不可或缺的一部分,它使得不同进程之间能够高效地共享资源和数据,协同完成复杂的任务。了解并掌握各种IPC机制,对于开发者而言,是提升程序性能和系统稳定性的重要手段。

    UNIX网络编程_卷2_进程间通信

    共享内存是进程间通信中最快的通信方式,因为它允许多个进程直接访问同一块内存区域。匿名共享内存没有名字标识,一般在创建它的父进程和子进程之间使用。而具名共享内存则通过系统中唯一的标识符来创建,允许任何两...

    Linux进程间通信

    在Linux操作系统中,进程间通信(IPC,Inter-Process Communication)是多个进程之间共享数据、交换信息的一种机制。它是多任务环境下实现协作和同步的重要手段。Linux提供了多种进程间通信方式,包括管道(Pipe)、...

    linux进程间通信ppt

    信号是进程间通信的一种快速机制,模拟硬件中断,用于通知进程发生了特定事件。进程可以通过`signal()`或`sigaction()`等函数来设置信号处理程序,接收和处理信号。 **8.4 信号量** 信号量是一种同步机制,用于控制...

    socket 实现进程间通信

    Socket编程在IT领域中扮演着重要的角色,尤其在进程间通信(IPC)方面。通过socket,不同的进程可以相互通信,实现数据交换和协调工作。本文将深入探讨如何利用socket来实现在同一台机器上三个进程间的通信,同时...

    UNIX Linux实验教程 4实验四Linux进程间通信.doc

    UNIX/Linux 操作系统提供了一组系统调用作为用户使用其进程间通信机制的接口。进程间通信是指在多任务计算机系统中,每个进程都具有自己独立的全局变量和局部变量,子进程几乎完全独立于创建它的进程。进程之间交换...

    Messenger进程间通信

    "Messenger进程间通信"是一种轻量级的IPC方式,常用于简单的双向通信场景。在这个主题中,我们将深入探讨Messenger服务端(Service)和客户端(Activity)的实现细节。 首先,`MessengerService`是服务端的核心组件...

    Linux进程间通信--Linux进程间通信

    Linux 进程间通信(IPC)是一种机制,允许不同的进程在操作系统中交换数据和信息。Linux 操作系统提供了多种进程间通信机制,包括管道、信号、消息队列、共享内存和套接口等。 Linux 进程间通信的重要性: 在 ...

Global site tag (gtag.js) - Google Analytics