linux进程间通信之------管道、命名管道

管道

概述

管道是一种两个进程间进行单向通信的机制。因为管道传递数据的单向性,管道又称为半双工管道。

管道的这一特点决定了器使用的局限性。管道是Linux支持的最初Unix IPC形式之一,shell中管道符“|”及tee命令就用到了管道。具有以下特点:

1、单向:数据只能由一个进程流向另一个进程(其中一个读管道,一个写管道);如果要进行双工通信,需要建立两个管道。

2、亲缘性:管道只能用于父子进程或者兄弟进程间通信。也就是说管道只能用于具有亲缘关系的进程间通信。

除了以上局限性,管道还有其他一些不足,如管道没有名字(匿名管道),管道的缓冲区大小是受限制的。管道所传输的是无格式的字节流。这就需要管道输入方和输出方事先约定好数据格式。虽然有那么多不足,但对于一些简单的进程间通信,管道还是完全可以胜任的。

 

实现原理

本质上说管道也是一种文件,它通过在内存中创建一个共享文件,使通信双方利用这个文件进行信息传递。

fork出子进程后,已经打开的文件描述符也会被子进程继承,管道就是利用了这个共享的文件描述符来工作的

仔细一想,感觉和共享内存差不多,介绍下区别:

1、管道需要进行四次数据拷贝,而共享内存只需要两次

管道:用户空间到内核、内核到内存、内存到内核、内核到用户空间

共享内存:用户空间到内存、内存到用户空间

2、管道使用循环队列实现,连续传输不限制大小,共享内存每次大小固定

3、共享内存可以随机访问映射文件位置,管道必须顺序读写 

 

管道接口

建立管道

int pipe(int filedes[2]);

filedes[0]为读取端,read用

filedes[0]为写入端,write用

关闭管道

colse

示例:

#include <stdio.h>
#include <string.h>
#include <wait.h>
#include <stdio.h>
 
#define MAX_LINE 64
 
int main()
{
	int pipeFd[2], ret;
	char buf[MAX_LINE + 1];
	const char * testbuf = "parent send data";
 
	if (pipe(pipeFd) == 0) {
		if (fork() == 0) 
        {
			ret = read(pipeFd[0], buf, MAX_LINE);
			buf[ret] = 0;

			printf("read data:%s", buf);
			close(pipeFd[0]);
		}
        else 
        {
			ret = write(pipeFd[1], testbuf, strlen(testbuf));
			ret = wait(NULL);

			close(pipeFd[1]);
		}
	}
	
	return 0;
}

命名管道FIFO

为了突破管道只能用于父子进程间通信,linux实现了一种命名管道的机制,其实现和管道类似,也需要创建时为其指定一个文件系统中的文件

 

创建FIFO

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo( const char *pathname, mode_t mode );

使用示例可以参考:这里 

 

管道和命名管道的局限性

1、传输的是比特流,没有消息边界的概念,

2、必须顺序读取,没有优先级的概念

3、使用的内核存储空间,允许滞留在管道中的数据容量有限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值