IPC机制:管道,信号量,共享队列,消息队列, 套接字。
管道,信号量,共享队列,消息队列,都只能在同一台主机上通信。
而套接字可以在不同电脑上通信。
在内核空间开辟。
管道大小
通过ulimit -a 来查看 也可以修改
管道通信的时候是半双工的。
可以在同一台主机上面的任意进程进行通信
首先 先使用 mkfifo + 文件名 创建管道文件
管道文件的大小为0
它不在磁盘上开辟空间,它是在内存上面开辟的。磁盘上面存放的只是这个文件的属性信息,如它是谁创建的,它是上面时候创建的,等等。
对管道操作的时候必须同时两个进程对其进行操作
一个的话就会阻塞住
案例
一个进程往管道中写,一个进程从管道中读
wfile.c
#include
#include
#include
#include
int main()
{
int fd = open("fifo",O_WRONLY);
if(-1 == fd)
{
std::cout<<"open erro"<<std::endl;
exit(-1);
}
while(1)
{
std::cout<<"please input"<<std::endl;
char buff[128]={0};
std::cin>>buff;
write(fd,buff,strlen(buff));
if(strncmp(buff,"end",3)==0)
{
break;
}
}
close(fd);
exit(0);
}
rfile.c
#include
#include
#include
#include
int main()
{
int fd = open("fifo",O_RDONLY);
if(-1 == fd)
{
std::cout<<"open erro"<<std::endl;
exit(-1);
}
while(1)
{
char buff[128]={0};
int n = read(fd,buff,127);
if(n <= 0 ||strncmp(buff,"end",3)==0)
{
break;
}
std::cout<<buff<<std::endl;
}
close(fd);
exit(0);
}
演示
只能在父子进程之间通信
向管道中写入的数据永远在内存中
有名管道可以在任意管道中通信,而无名管道只能在父子进程中通信
管道为满,写操作会阻塞
管道为空,读操作会阻塞
父进程往管道中写,子进程从管道中读
#include
#include
#include
#include
int main()
{
int fd[2];
int res = pipe(fd);
if(-1 == res )
{
std::cout<<"pipe erro"<<std::endl;
exit(-1);
}
pid_t pid = fork();
if(-1 == pid)
{
std::cout<<"fork erro"<<std::endl;
exit(-1);
}
if(pid == 0)
{
close(fd[1]);
char buff[128]={0};
int n = read(fd[0],buff,127);
std::cout<<buff<<std::endl;
close(fd[0]);
}else
{
close(fd[0]);
write(fd[1],"hello",5);
close(fd[1]);
}
exit(0);
}
演示:
管道实际就是有两个指针,一个负责写,一个负责读,两个指针之间的则为管道中暂存的数据,当两个指针指向同一个位置时,则表示此时管道为空,当负责写的指针写的管道的末尾没有空间时,则会返回到首部去进行写。
假如说在使用读的时候,没有关闭写,当另一端的写端关闭时,而此时进行read的时候,它检测到还有一个写端,并不会立即返回0,而是进行阻塞。