进程间通信之匿名管道

进程间通信的5中方式:

有名管道,匿名管道,systemv,posix消息队列,信号量,文件共享映射,

注意,5种进程间通信均操作的内核空间

首先我们来浅谈下匿名管道pipe

匿名管道是通过环形队列实现的,可实现节省空间和避免溢出等问题。

匿名管道有两个特点,一个是方向性,另一个是具有流向

匿名管道只能解决父子进程之间的通信,一般使用pipe时在fork之前进行

匿名管道一共四个文件描述符,两个读,两个写,分别指向管道的两端,而只有这四个文件描述符全部关闭,管道才可以被销


匿名管道的特点:1.只支持单项数据流

                          2.只有父子进程可通信

                          3.没有名字

                          4.管道缓冲区是有限的

                        5.管道所传送的是无格式字节流,这就要求读出方和写入方约定好格式,比如多少字节算一个消息。


匿名管道的API  pipe(int fd[2])如果成功,则在内存中开辟内核缓冲区,并将管道的读端和写端连通

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>

#define	MSG	"Test Message...."


int main(void)
{
	int fds[2];
	pid_t pid;
	//父进程创建管道
	pipe(fds);
	//创建子进程
	pid = fork();
	//确定通信方向:父写子读,关闭无用文件描述符
	if(pid > 0){
		close(fds[0]);
		printf("Parent pid:%d\n",getpid());
		sleep(5);
		printf("parent send msg:%s\n",MSG);
		write(fds[1],MSG,strlen(MSG));
		close(fds[1]);
		while(1);
		
	}else if(pid == 0){
		char buf[1024];
		int len;
		int flags;
		close(fds[1]);
		printf("Child pid:%d\n",getpid());
		flags = fcntl(fds[0],F_GETFL);
		flags|=O_NONBLOCK;
		fcntl(fds[0],F_SETFL,flags);//改变管道的非阻塞属性
tryagain:
		len = read(fds[0],buf,sizeof(buf));
		if(len == -1){
			if(errno == EAGAIN){
				printf("child read kernerl buf tryagain....\n");
				sleep(1);
				goto tryagain;	
			}
		}
		printf("Child recv msg:\n");
		write(STDOUT_FILENO,buf,len);
		close(fds[0]);
	}else{
		perror("fork error:");
		exit(0);
	}
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值