13.无名管道通讯编程

?

1.进程间的通信:

Linux作为典型的多进程操作系统,进程与进程之间肯定需要信息交流,这就需要进程通信。

2.进程通信的目的:

????1.数据传输:一个进程需要将数据发送给另一个进程。

????2.资源共享:多个进程之间共享同样的资源。

????3.通知事件:一个进程需要向另一个/组进程发送信息,通知他们发生了某些事情。

????4.进程控制:有些进程希望完全控制另一个进程的执行,例如Debug进程。此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道他的状态改变。

?

3.通讯发展:

????Linux进程间通信(IPC:Interprocess Communication)由以下几个部分发展而来:

  1. UNIX进程间通信。
  2. 基于System V进程间通信
  3. POSIX进程间通信。

?

4.通讯发展-posix:

POSIX(Portable Operating System Interface)表示可移植操作系统接口。电气和电子工程师协会IEEE最初开发 POSIX 标准,是为了提高 UNIX 环境下应用程序的可移植性。然而,POSIX 并不局限于 UNIX,许多其它的操作系统,例如Microsoft Windows都支持POSIX 标准。

?

5.通讯方式:

Linux进程间通讯的主要方式有:

1、无名管道(pipe)

2、有名管道(FIFO)

3、信号(signal)

4、消息队列

5、共享内存

6、信号量

7、套接字(socket)

?

6.管道通信:

一个进程在管道的尾部写入数据,另一个进程从管道的头部读出数据。管道包括无名管道和有名管道两种,前者只能用于父进程和子进程间的通信,后者可用于运行于同一系统中的任意两个进程间的通信。

?

7.管道通信的特点:

1. 管道通讯是单向的,有固定的读端和写端。

2. 数据被进程从管道读出后,在管道中该数据就不存在了。

3. 当进程去读取空管道的时候,进程会阻塞。

4. 当进程往满管道写入数据时,进程会阻塞。

5. 管道容量为64KB

?

8.无名管道:

在Linux系统中,无名管道一旦创建完成后,操作无名管道等同于操作文件。无名管道的读端被视作一个文件,要读出无名管道的数据,需要找到读端文件;无名管道的写端也被视作一个文件,要往一个无名管道写数据,就是操作写端文件。

?

一、无名管道

在Linux系统中,无名管道一旦创建完成后,操作无名管道等同于操作文件。因此可以使用read,write,close等函数来访问无名管道。

?

?

?

?

?

?

无名管道:pipe

函数的原型:man 2 pile:

NAME

pipe, pipe2 - create pipe

?

SYNOPSIS

#include <unistd.h>

?

int pipe(int pipefd[2]);

?

#define _GNU_SOURCE

#include <unistd.h>

?

int pipe2(int pipefd[2], int flags);

?

DESCRIPTION

pipe() creates a pipe, a unidirectional data channel that can be used for

interprocess communication. The array pipefd is used to return two file

descriptors referring to the ends of the pipe. pipefd[0] refers to the read

end of the pipe. pipefd[1] refers to the write end of the pipe. Data written

to the write end of the pipe is buffered by the kernel until it is read from

the read end of the pipe. For further details, see pipe(7).

?

If flags is 0, then pipe2() is the same as pipe(). The following values can be

bitwise ORed in flags to obtain different behavior:

?

O_NONBLOCK Set the O_NONBLOCK file status flag on the two new open file

descriptions. Using this flag saves extra calls to fcntl(2) to

achieve the same result.

O_CLOEXEC Set the close-on-exec (FD_CLOEXEC) flag on the two new file

descriptors. See the description of the same flag in open(2) for

reasons why this may be useful.

?

RETURN VALUE

On success, zero is returned. On error, -1 is returned, and errno is set

appropriately.

?

ERRORS

EFAULT pipefd is not valid.

?

EINVAL (pipe2()) Invalid value in flags.

?

EMFILE Too many file descriptors are in use by the process.

?

ENFILE The system limit on the total number of open files has been reached.

?

VERSIONS

pipe2() was added to Linux in version 2.6.27; glibc support is available start-

ing with version 2.9.

?

CONFORMING TO

pipe(): POSIX.1-2001.

?

pipe2() is Linux-specific.

EXAMPLE

The following program creates a pipe, and then fork(2)s to create a child pro-

cess; the child inherits a duplicate set of file descriptors that refer to the

same pipe. After the fork(2), each process closes the descriptors that it

doesn‘t need for the pipe (see pipe(7)). The parent then writes the string

contained in the program‘s command-line argument to the pipe, and the child

reads this string a byte at a time from the pipe and echoes it on standard out-

put.

?

#include <sys/wait.h>

#include <assert.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

?

int

main(int argc, char *argv[])

{

int pipefd[2];

pid_t cpid;

char buf;

?

assert(argc == 2);

?

if (pipe(pipefd) == -1) {

perror("pipe");

exit(EXIT_FAILURE);

}

?

cpid = fork();

if (cpid == -1) {

perror("fork");

exit(EXIT_FAILURE);

}

?

if (cpid == 0) { /* Child reads from pipe */

close(pipefd[1]); /* Close unused write end */

?

while (read(pipefd[0], &buf, 1) > 0)

write(STDOUT_FILENO, &buf, 1);

?

write(STDOUT_FILENO, "\n", 1);

close(pipefd[0]);

_exit(EXIT_SUCCESS);

?

} else { /* Parent writes argv[1] to pipe */

close(pipefd[0]); /* Close unused read end */

write(pipefd[1], argv[1], strlen(argv[1]));

close(pipefd[1]); /* Reader will see EOF */

wait(NULL); /* Wait for child */

exit(EXIT_SUCCESS);

}

}

SEE ALSO

fork(2), read(2), socketpair(2), write(2), popen(3), pipe(7)

?

COLOPHON

This page is part of release 3.22 of the Linux man-pages project. A descrip-

tion of the project, and information about reporting bugs, can be found at

http://www.kernel.org/doc/man-pages/.

函数的原型:

int pipe(int pipefd[2]);

该函数的功能是创建无名管道。需要的头文件是unistd.h。返回值:

成功返回0,失败返回-1.

该函数有两个参数:

参数是一个数组,该数组有两个元素,一个读端,一个写端,返回值是两个文件描述符。

Pipefd[0]是读端的fd,pipefd[1]是写端的fd。

?

实例:创建一个管道用于父子进程间的通信:

pipe.c:

#include <unistd.h>

#include <stdio.h>

?

void main(){

?

????pid_t pid=0;

????int pipefd[2];

????char my_buf[12];

?

????//before fork() create a pipe

????pipe(pipefd);

?

????//create a child process

????pid = fork();

????if(pid>0){

????????//father write something into pipe

????????write(pipefd[1],"forfish",8);

????????wait();//wait child process

????????close(pipefd[1]);//close pipe

????????exit(0);

????}

????if(pid == 0){

????????//son

????????read(pipefd[0],my_buf,8);

????????printf("child read %s \n",my_buf);

????????close(pipefd[0]);

????????exit(0);

????}

}

?

运行结果:

我们看到上面的无名管道操作是基于父子进程的操作,因为管道一旦创建,就是两个文件,一个读端文件,一个写端文件。我们操作管道就是操作这两个文件。

?

?

?

时间: 2024-10-26 05:30:27

13.无名管道通讯编程的相关文章

无名管道通讯编程

创建无名管道用于父子间进程通信. 1.无名管道概念:无名管道又称pipe,是Linux所支持的IPC方式的一种,它具有以下特点: 1)只能用于具有血缘关系的进程之间. 2)属于半双工的通信模式,具有固定的读端和写端 3)是一种特殊的文件,存在于内存中,可通过read.write对其操作. 2.无名管道的用法 因为pipe存在于内存中,所以无法像操作普通文件那样通过指定路径来打开文件.通常的做法是在父进程中创建管道,再创建子进程.由于子进程继承了父进程打开的文件描述符,所以父子进程就可以通过创建的

无名管道与有名管道通讯编程

管道通讯:一个进程在管道的尾部写入数据,另一个进程从管道的头部读出数据.管道包括无名管道和有名管道两种,前者只能用于父进程和子进程间的通信,后者可用于运行于同一系统中的任意两个进程间的通信. 管道通讯的特点: 1. 管道通讯是单向的,有固定的读端和写端. 2. 数据被进程从管道读出后,在管道中该数据就不存在了. 3. 当进程去读取空管道的时候,进程会阻塞. 4. 当进程往满管道写入数据时,进程会阻塞. 5. 管道容量为64KB(#define PIPE_BUFFERS 16,include/li

[国嵌攻略][080][无名管道通讯]

通讯目的 1.数据传输 一个进程需要将数据发送给另外一个进程. 2.资源共享 多个进程之间共享同样的资源. 3.通知事件 一个进程需要向另外一个/组进程发送消息,通知它们发生了某事件. 4.进程控制 有些进程希望完全控制另外一个进程的执行,此时控制进程希望能够拦截另外一个进程的所有操作,并能够及时知道它的状态改变. 通信方式 1.无名管道(pipe):数据传输 2.有名管道(fifo):数据传输 3.信号(signal):通知事件 4.消息队列 5.内存共享 6.信号量:资源共享 7.套接字(s

第11课-无名管道通讯

1.进程间通讯的目的(1)数据传输(2)资源共享(3)通知事件(4)进程控制2.通讯发展(1)UNIX进程间通讯(2)基于System V进程间通讯(3)POSIX进程间通讯3.POSIX标准4.进程间通讯的主要方式(1)无名管道(2)有名管道(3)信号(4)消息队列(5)共享内存(6)信号量(7)套接字5.管道通信(1)一个进程在管道尾部写入数据,另一个进程管道头部读取数据(2)无名管道:只能用于父进程子进程之间的通讯(3)有名管道:可以用于任意两个进程间的通讯6.管道特点:(1)管道通讯是单

有名管道通讯编程

创建2个进程,在A进程中创建一个有名管道,并向其写入数据,通过B进程从有名管道中读出数据. 有名管道又称命名管道,可用于无亲缘关系的进程之间通信,在某些特点上类似于文件. 用法:通过mkfifo创建有名管道,之后就可以想操作普通文件通过open().close().write().以及read()对它进行相应操作. 1.创建一个有名管道--mkfifo 头文件:#include<sys/types.h>,#include<sys/stat.h> 原型:int mkfifo(cons

linux应用开发-无名管道编程

linux应用开发-无名管道编程 一 linux进程间通信(ipc) 1 UNIX进程间通信 2 基于System V的通信 3 POSIX通信 二 七种通信方式 1 管道 一个进程在管道的尾部写入数据,另一个进程从管道的头部 读出数据.管道包括无名管道和有名管道两种,前者只能用 于父进程和子进程间的通信,后者可用于运行于同一系统中 的任意两个进程间的通信. 分类: 无名管道(pipo):用于父进程和子进程间的通信 有名管道(FIFO):用于运行于同一系统中的任意两个进程间的通信 特点: 1 管

Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)

一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o test.i 编译:   不同平台使用汇编语言不同,汇编将高级语言编译成汇编语言: gcc -S test.c -o test.s 汇编:   将汇编语言翻译成二进制代码: gcc -c test.c -o test.o 链接:   包含各函数库的入口,得到可执行文件: gcc -o test test.c (2

第13篇-JAVA 网络编程

第13篇-JAVA 网络编程 每篇一句 比我强大的人都在努力我还有什么理由不拼命 初学心得 不去追逐你所渴求你将永远不会拥有 (笔者JEEP/711)[JAVA笔记 | 时间:2017-04-22| JAVA 网络编程 ] 1.网络编程基本概念 1.什么是计算机网络 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备通过通信线路连接起来在网络操作系统网络管理软件及网络通讯协议的管理和协调下实现资源共享和信息传递的计算机系统 把分布在不同地理区域的计算机与专门的外部设备用通讯线路互

管道通信之无名管道---pipe()

pipe()函数在子进程产生之前就应该存在. 父子进程之间只进行一次传递 1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:onepipe.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #inclu