管道的特点
- 管道其实是一个在内核内存中维护的缓冲器,这个缓冲器的存储能力时有限的,不同的操作系统大小不一定相同。
- 管道拥有文件的特质:读操作、写操作,匿名管道没有文件实体,有名管道由文件实体,但不存储数据。可以按照操作文件的方式对管道进行操作。
- 一个管道是一个字节流,试用管道时不存在消息或消息边界的概念,从管道读取数据的进程可以读取任意大小的数据块,而不管写入进程写入管道的数据块的大小是多少。
- 通过管道传递的数据是顺序的,从管道里读出数据的顺序和它们被写入到管道里的顺序是一致的。
- 在管道中的数据传输的方向是单向的,一端用于写入,一端用于读取,管道是半双工的。
- 从管道读数据是一次性操作,数据一旦被读走,它就从管道中被抛弃,释放空间以便写入更多数据,在管道中无法使用lseek()函数来随机的访问数据。
- 匿名管道只能在具有公共祖先的进程(父进程与子进程、或者两个兄弟进程、具有亲缘关系)之间使用
匿名管道
- 管道也叫无名(匿名)管道。它是UNIX系统IPC的最古老形式。所有的UNIX系统都支持这种通信机制。
- 统计一个目录中文件数目命令:
ls | wc -l
,为了执行该命令,shell创建了两个进程分别来执行 ls 和 wc。
在Linux终端下输入命令:man 2 pipe
查看pipe函数的具体描述:
NAME
pipe, pipe2 - create pipe
SYNOPSIS
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建一个匿名管道,用来进程间通信
参数:
int pipefd[2]:这个参数是个传出参数
pipefd[0]:对应的是管道的读端
pipefd[1]对应的是管道的写端
返回值:
成功返回0
失败返回-1
注意:匿名管道只能用于具有亲缘关系的管道之间。管道默认是阻塞的如果管道中没有数据
read阻塞,如果管道满了write阻塞。
下面是pipe函数的简单案例:
- 父子进程交叉收发信息
- 查看管道缓冲大小函数
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using std::cout;
using std::endl;
namespace jj01{
//子进程发送数据给父进程,父进程读取数据输出
//父子进程交叉收发信息
void test(){
//在fork之前创建管道
int pipefd[2];
int ret = pipe(pipefd);
if(ret == -1)
perror("pipe");
//创建子进程
pid_t pid = fork();
char buf[1024] = {0};
if(pid > 0){
//父进程
//从管道读取数据
cout << "i am parent,pid: "<<getpid()<<endl;
//不断从管道中读数据
while(1){
int leng = read(pipefd[0],buf,sizeof(buf));
cout << "parent recv : "<<buf<<" pid:"<<getpid()<<endl;
//管道中写数据
const char *str = "hello,i am parent";
write(pipefd[1],str,strlen(str));
sleep(1);
}
}
else if(pid == 0){
//子进程
cout << "i am child,pid: "<<getpid()<<endl;
//不断向管道中写数据
while(1){
const char *str = "hello,i am child";
write(pipefd[1],str,strlen(str));
sleep(1);
//从管道中读数据
int leng = read(pipefd[0],buf,sizeof(buf));
cout << "child recv : "<<buf<<" pid:"<<getpid()<<endl;
}
}
}
}
namespace jj02{
/*
查看管道缓冲大小命令:ulimit -a
查看管道缓冲大小函数
#include <unistd.h>
long fpathconf(int fd, int name);
参数:
int fd:文件描述符
int name:_PC_PIPE_BUF 获取管道的大小
*/
void test(){
int pipefd[2];
int ret = pipe(pipefd);
//获取管道的大小
long psize = fpathconf(pipefd[0],_PC_PIPE_BUF);
cout <<"管道的大小:"<< psize << endl;
}
}
int main(){
//jj01::test();
jj02::test();
return 0;
}
标签:pipe,--,pipefd,管道,间通信,int,匿名,进程,include
From: https://www.cnblogs.com/nakjima/p/17276064.html