管道文件为内存及文件,没有名称(匿名管道)
如何让两个进程看到同一个管道文件?
通过fork创建子进程完成。
匿名管道可以用于父子进程之间的通信。
匿名管道是一个固定大小的缓冲区,写端写满后就会阻塞,等待读取。
管道的特征:
操作系统间接提供内存空间。(管道的大小是有限的)
管道读写的特征:
读快写慢:
如果管道中没有了数据,读端在读,默认会直接阻塞当前正在读取的进程。
读慢写快:
管道是一个固定大小的缓冲区。
写端写满的时候会阻塞,等对方进行读取。
管道读取得时候不是按行读取,而是按指定大小读取的。大小满足后一次性读取大量数据。
写关闭继续读
将管道中数据读取完毕后,结束进程。
读关闭继续写:
管道是单向通信的,这样的行为没有意义。
OS会终止写端,会给写端发信号,终止写端。
验证:
#include<iostream>
#include<cstdio>
#include<string>
#include<cassert>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<cstring>using namespace std;
int main()
{//创建管道文件,打开读写端int fds[2]; int n=pipe(fds);assert(n==0);cout<<"fds[0]:"<<fds[0]<<endl;//读cout<<"fds[1]:"<<fds[1]<<endl;//写pid_t id=fork();assert(id>=0);if(id==0){//子进程close(fds[0]);int cnt=0;const char* s="我是子进程,我真正发消息";while(true){cnt++;char buffer[1024];snprintf(buffer,sizeof buffer,"child->parent: %s[%d][%d]\n",s,cnt,getpid());write(fds[1],buffer,strlen(buffer));sleep(1);}//子进程close(fds[1]);//子进程关闭写端cout<<"子进程关闭写端"<<endl;exit(0);}//父进程的通信代码close(fds[1]);//父进程的通信代码while(true){char buffer[1024];//把读到的内容当字符串处理//如果管道中没有了数据,读端在读,默认会直接阻塞当前正在读取的进程。ssize_t s=read(fds[0],buffer,sizeof(buffer)-1);if(s>0) {buffer[s]=0;cout<<"Get Message# "<<buffer<<"| my pid: "<<getpid()<<endl; }else if(s==0){cout<<"read: "<<s<<endl;break;}}n=waitpid(id,nullptr,0);assert(n==id);//cout<<"hello c++"<<endl;close(fds[0]);return 0;
}