管道

匿名管道(pipe)

管道是IPC最基本的一种实现机制。我们都知道在Linux下“一切皆文件”,其实这里的管道就是一个文件。管道实现进程通信就是让两个进程都能访问该文件。 
管道的特征: 
①只提供单向通信,也就是说,两个进程都能访问这个文件,假设进程1往文件内写东西,那么进程2 就只能读取文件的内容。 
②只能用于具有血缘关系的进程间通信,通常用于父子进程建通信 
③管道是基于字节流来通信的 
④依赖于文件系统,它的生命周期随进程的结束结束(随进程) 

⑤其本身自带同步互斥效果

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

int main()
{
	int fds[2];
	if(pipe(fds)==-1) perror("pipe"),exit(1);
	pid_t pid;
	if((pid=fork())==-1) perror("fork"),exit(1);

	if(pid==0)
	{
		close(fds[0]);
		char* msg="cdsada";
		write(fds[1],msg,strlen(msg));
		close(fds[1]);
	}
	else if(pid>0)
	{
		close(fds[1]);
		char buf[20]={};
		read(fds[0],buf,20);
		printf("buf=[%s]\n",buf);
		close(buf[0]);
	}
}

使用管道需要注意的4种特殊情况:

  • 如果所有指向管道写端的文件描述符都关闭了,而仍然有进程从管道的读端读数据,那么文件内的所有内容被读完后再次read就会返回0,就像读到文件结尾。
  • 如果有指向管道写端的文件描述符没有关闭(管道写段的引用计数大于0),而持有管道写端的进程没有向管道内写入数据,假如这时有进程从管道读端读数据,那么读完管道内剩余的数据后就会阻塞等待,直到有数据可读才读取数据并返回。
  • 如果所有指向管道读端的文件描述符都关闭,此时有进程通过写端文件描述符向管道内写数据时,则该进程就会收到SIGPIPE信号,并异常终止。
  • 如果有指向管道读端的文件描述符没有关闭(管道读端的引用计数大于0),而持有管道读端的进程没有从管道内读数据,假如此时有进程通过管道写段写数据,那么管道被写满后就会被阻塞,直到管道内有空位置后才写入数据并返回。

命名管道(FIFO)

上述管道虽然实现了进程间通信,但是它具有一定的局限性:首先,这个管道只能是具有血缘关系的进程之间通信;第二,它只能实现一个进程写另一个进程读,而如果需要两者同时进行时,就得重新打开一个管道。 
为了使任意两个进程之间能够通信,就提出了命名管道(named pipe 或 FIFO)。 
1、与管道的区别:提供了一个路径名与之关联,以FIFO文件的形式存储于文件系统中,能够实现任何两个进程之间通信。而匿名管道对于文件系统是不可见的,它仅限于在父子进程之间的通信。 
2、FIFO是一个设备文件,在文件系统中以文件名的形式存在,因此即使进程与创建FIFO的进程不存在血缘关系也依然可以通信,前提是可以访问该路径。 
3、FIFO(first input first output)总是遵循先进先出的原则,即第一个进来的数据会第一个被读走。


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

int main(void)
{
	mkfifo("my.p",0644);
	int fd=open("my.p",O_RDWR);
	if(fd==-1) perror("open"),exit(1);
	while(1)
	{
		char buf[1024]={};
		if(read(fd,buf,1024)<=0) break;
		printf("%s\n",buf);
	}
	close(fd);
}
  • 命名管道与匿名管道使用的区别: 
    命名管道创建完成后就可以使用,其使用方法与管道一样,区别在于:命名管道使用之前需要使用open()打开。这是因为:命名管道是设备文件,它是存储在硬盘上的,而管道是存在内存中的特殊文件。但是需要注意的是,命名管道调用open()打开有可能会阻塞,但是如果以读写方式(O_RDWR)打开则一定不会阻塞;以只读(O_RDONLY)方式打开时,调用open()的函数会被阻塞直到有数据可读;如果以只写方式(O_WRONLY)打开时同样也会被阻塞,知道有以读方式打开该管道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值