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

进程间通信(三)

阅读更多


管道调用

我们已经了解了高层的popen函数,现在我们继续来了解低层的pipe函数。这个函数提供了一个在两个函数之间传递数据的方法,而不必调用shell来解释所请求的命令的。同时他也为我们提供了更多的数据读写控制。

pipe函数的原型如下:

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

pipe函数接受一个两个整数文件描述符的数组作为参数。他会使用两个新的文件描述符来填充这个数据并且返回一个零值。如果失败则会返回-1并且设置errno来指明失败原因。Linux手册页中所定义的错误如下:

EMFILE:进程正在使用的文件描述符过多
ENFILE:系统文件表已满
EFAULT:文件描述符不可用

返回的两个文件描述符以一个特殊的方式相连接。任何写入file_descriptor[1]的数据可以由file_descriptor[0]中读取。数据以先进先出的方式进行处理,通常简记为FIFO。这就意味着如果我们向file_descriptor[1]中写入字节1,2,3,那么由file_descriptor[0]中的读取就会产生1,2,3。这与堆栈不同,后者以后进先出的方式进行操作,通常简记为LIFO。

注意:在这里我们要清楚,这些是文件描述符,而不是文件流,所以我们必须使用低层的read与write调用来访问数据,而不是fread与fwrite。

下面的程序,pipe1.c,使用pipe来创建一个管道。

试验--pipe函数

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

int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
char buffer[BUFSIZ +1];

memset(buffer,'\0',sizeof(buffer));

if(pipe(file_pipes) == 0)
{
data_processed = write(file_pipes[1],some_data,strlen(some_data));
printf("Wrote %d bytes\n",data_processed);
data_processed = read(file_pipes[0],buffer,BUFSIZ);
printf("Read %d bytes: %s\n",data_processed,buffer);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}

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

$ ./pipe1
Wrote 3 bytes
Read 3 bytes: 123

工作原理

这个程序使用两个文件描述符file_pipes[]来创建一个管道。然后他使用文件描述符file_pipes[1]向管道中写入数据,并且由file_pipes[0]中读取。注意管道有内部缓冲,从而可以在两个调用write与read之间存储数据。

我们应该清楚尝试使用file_pipes[0]写入数据,或是使用file_pipes[1]读取数据的效果是未定义的,所以这样的行为结果会非常奇怪,并且也许会毫无警告的发生改变。在作者的系统上,这样的调用会失败并且返回-1,这至少保证了是很容易捕获这个错误的。

粗看起来这个管道的例子似乎并没有为我们提供任何我们使用一个简单的文件不能完成的任务。管道的真正优点在我们希望在两个进程之间传递数据时才会体现出来。正如我们在第12章所看到的,当一个程序使用fork调用创建一个新进程时,以前打开的文件描述符会保持打开。通过在原始进程中创建一个管道,然后通过fork创建一个新进程,我们可以由一个进程向另一个进程传递数据。

试验--使用fork的管道

1 这是pipe2.c。这个程序的开始部分与第一个例子类似,直到我们调用fork。

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

int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
char buffer[BUFSIZ + 1];
pid_t fork_result;

memset(buffer,'\0',sizeof(buffer));

if(pipe(file_pipes)==0)
{
fork_result = fork();
if(fork_result == -1)
{
fprintf(stderr,"Fork failure");
exit(EXIT_FAILURE);
}

2 我们已经保证fork正常工作,所以如果fork_result等于0,我们是在子进程中:

if(fork_result == 0)
{
data_processed = read(file_pipes[0],buffer,BUFSIZ);
printf("Read %d bytes: %s\n",data_processed,buffer);
exit(EXIT_SUCCESS);
}

3 否则,我们一定在父进程中:
else
{
data_processed = write(file_pipes[1],some_data,strlen(some_data));
printf("Wrote %d bytes\n",data_processed);
}
}
exit(EXIT_SUCCESS);
}

当我们运行这个程序,我们得到与前面一样的输出:

$ ./pipe2
Wrote 3 bytes
Read 3 bytes: 123

我们也许会发现实际上命令提示符会在输出的最后部分之前出现,但是我们在这里已经对输出进行整理从而使其更易于阅读。

工作原理

首先这个程序使用pipe调用创建一个管道。然后他使用fork调用来创建一个新的进程。如果fork调用成功,父进程就会向管道写入数据,而子进程由管道中读取数据。父子进程都会在一个简单的write与read之后退出。如果父进程在子进程之前退出,我们就会看到shell提示符出现在两个输出之间。

尽管这个程序与前面的管道例子十分相似,但是我们已经通过使用单独的进程用于读写而向前进了一大步.

分享到:
评论

相关推荐

    linux进程间通信与同步.pdf

    #### 三、深入理解Linux下的进程间通信手段 Linux下的进程间通信手段主要包括: 1. **管道(Pipe)**:管道是一种半双工的通信方式,只能在一个方向上传输数据。它主要用于父子进程之间的通信。 2. **有名管道(Named...

    进程间通信

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

    linux 操作系统进程间通信 ppt

    Linux 操作系统进程间通信 Linux 操作系统的进程间通信是指在多个进程之间实现信息交换和协作的机制。进程间通信是操作系统中非常重要的一部分,涉及到进程之间的信息交换、同步和互斥等问题。 在 Linux 操作系统...

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

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

    Linux进程间通信.pdf

    ### Linux进程间通信详解 #### 引言 在现代操作系统如Linux中,进程间通信(IPC,Inter-Process Communication)是实现多进程协同工作的重要机制。通过IPC,不同进程能够共享信息、同步状态以及协作完成复杂的任务...

    socket 实现进程间通信

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

    Windows下进程间通信

    在给定的标题“Windows下进程间通信”和描述中,涉及了三种主要的IPC技术:内存文件映射、信号量和线程池。下面将详细阐述这些知识点。 1. 内存文件映射(Memory-Mapped Files): 内存文件映射是一种在多个进程...

    进程间通信.rar

    进程间通信(IPC,Inter-Process Communication)是操作系统中一种重要的技术,允许不同进程之间交换数据,协同工作。在C++编程中,实现进程间通信通常涉及到多种方法,包括共享内存、管道和套接字(socket)。下面...

    操作系统实验报告(LINUX进程间通信)

    操作系统实验报告(LINUX进程间通信) 操作系统实验报告(LINUX进程间通信)是操作系统课程的一部分,涵盖了Linux进程间通信的原理和应用,包括消息队列、C/S结构等内容。下面将对这些知识点进行详细的解释。 一、...

    Linux 进程间通信

    ### Linux 进程间通信详解 #### 一、管道及有名管道 在深入探讨Linux中的进程间通信(IPC)机制之前,我们先了解一个基本概念:**进程**。进程是程序执行的一个实例,每个进程都有自己的地址空间。当多个进程需要...

    进程间通信之套接字( socket )——完整代码

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

    Linux下的进程间通信 详解

    ### Linux下的进程间通信详解 #### 一、引言 在多进程的环境中,进程间通信(IPC,Inter-Process Communication)是操作系统中一个至关重要的功能。Linux作为一款优秀的开源操作系统,提供了多种进程间通信机制,...

    delphi进程间通信

    在编程领域,进程间通信(IPC,Inter-Process Communication)是一项关键的技术,它允许不同的进程之间交换数据,协同工作。Delphi,作为一个强大的面向对象的编程环境,提供了多种方式进行进程间通信。本篇文章将...

    Linux进程间通信方式之socket使用实例

    ### Linux进程间通信方式之socket使用实例详解 #### 一、引言 在现代操作系统中,进程间的通信(IPC)是实现多进程协同工作的重要手段之一。Linux提供了多种进程间通信的方法,包括信号量、消息队列、共享内存以及...

    UNIX网络编程 第2卷 进程间通信.pdf(带书签)

    《UNIX网络编程 第2卷 进程间通信》是一本深入探讨UNIX环境下进程间通信机制的权威技术书籍。该书共分为四部分,涵盖了从基础套接口编程到高级套接口编程的多个方面,旨在为读者提供全面的进程间通信知识和编程实践...

    linux进程间通信详解

    在Linux操作系统中,进程间通信(IPC,Inter-Process Communication)是多个进程之间共享数据、交换信息的关键技术。本文将深入探讨Linux进程间通信的多种方法、原理以及实际应用。 一、管道(Pipe) 管道是一种...

    进程间通信之消息队列 ( message queue )——完整代码

    进程间通信之消息队列 ( message queue ) 消息队列是消息的链表,具有特定的格式,并由消息队列标识符标识. 七种进程间通信方式: 一.无名管道( pipe ) 二.有名管道( fifo ) 三.共享内存 ( shared memory ) 四....

    Windows进程间通信

    在Windows操作系统中,进程间通信(IPC,Interprocess Communication)是一种技术,允许不同的进程之间共享数据、协调工作或交换信息。这种技术对于多线程和多进程应用的开发至关重要,尤其是在分布式系统和并发编程...

    深刻理解Linux进程间通信

    ### 深刻理解Linux进程间通信 #### Linux进程间通信概述 进程间通信(Inter-Process Communication,简称IPC)是指在多进程环境下,不同进程之间进行数据交换或同步操作的技术。Linux作为一款广泛使用的开源操作...

    Binder与进程间通信

    #### 三、Binder与进程间通信的实现 接下来我们将深入了解Binder如何用于实现进程间通信。 - **客户端获取服务代理**:客户端如果需要调用远程服务,首先需要通过ServiceManager获取该服务的代理对象。例如,在...

Global site tag (gtag.js) - Google Analytics