Linux系统编程 Part3管道通信

IPC(进程间通信 Inter Process Comnunication)
目前常用的通信方式:

  • 管道 最简单
  • 信号 开销最小
  • 共享映射区域 在无关系的进程间通信
  • 本地套接字 最复杂,最稳定
文件类型

-文件
d目录
l 符号链接

伪文件(不占用磁盘空间):
s套接字
b块设备
c字符设备
p管道 (内核缓冲区)

查看缓冲区大小 #ulimit -a    512字节*8

在这里插入图片描述
管道局限性(其实现方式为环形队列):

  • 数据自己读不能自己写
  • 数据一旦被读走,便不再存在
  • 半双工,数据只能在一个方向上流动 (同时刻)
  • 只能在有公共祖先的进程见使用管道通信
#include<stdio.h>
#include<unistd.h>
int main(){
   int fd[2];
   
   //fd[0] 读管道   fd[1]写管道 
   //pipe返回 0 则成功 否则返回-1
   int ret=pipe(fd);
   printf("ret==%d\n",ret);
   if (ret==-1){
   	perror("pipe error:\n");
   	exit(1);
   } 

   pid_t pid=fork();
   if(pid<0){
   	perror("pipe error:\n");
   	exit(1);
   }else if(0==pid){
   //	#子进程读数据
   	close(fd[1]);
   	char buf[1024];
   	//read返回值 是实际读取到的字节数。
   	ret=read(fd[0],buf,sizeof(buf));

   printf("ret==%d\n",ret);
   	//末尾读到0	
   	if(0==ret)
   		printf("--------\n");
   	//将buf写入第一个参数所指的文件内。
   	write(1,buf,ret);
   	printf("Son successfully output!\n");		
   }else {
   	sleep(1);
   	close(fd[0]);
   	write(fd[1],"strstr   str\n",13);	
   //	wait(NULL);
   
   }
}

练习:借助共同的文件传递数据

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

int main(){

	pid_t pid;
	pid=fork();
	
	if(pid<0){
		perror("fork error!\n");
		exit(1);
	}else if(pid==0){
	
		int fd=open("new.txt",O_WRONLY);		
		char ame[]="acffdsds ss\n";
		int len=strlen(ame);
		write(fd,ame,len);
		close(fd);	
		printf("Son exit_____\n");
	}else{
		sleep(1);
		int fd=open("new.txt",O_RDONLY);

		char buff[1024];
		read(fd,buff,1024);
		printf("%s\n",buff);
		close(fd);
		printf("father eixt_______\n");

	}

	return 0;
}

mmap函数
mmap获取文件指针操作文件
创建的映射区权限要小于打开文件的权限;
创建映射区时有一次隐式的读操作。

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

int main(){
	
	int fd=open("mytext.txt",O_CREAT|O_RDWR,0644);
	if(fd<0)
		perror("open error\n");
	//文件截断为4字节  返回的len不代表大小 
	//注意truncate 和 ftruncate 的参数区别
	ftruncate(fd,4);

	//最后一个参数offset文件指针偏移量。必须是4096的整数倍  mmap对文件创建映射。
	//映射区由MMU创建 单位为页。
	//  映射区权限prot
	//第二参数 文件大小 不可为0  -->映射区大小不可为0
	char *p =mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	//不检查返回值会死的很难看?
	if(MAP_FAILED==p){
		perror("mmap error:");
		exit(1);
	}

	//通过指针操作内存
	strcpy(p,"ac");
	//关闭mmap
	int ret=munmap(p,4);
	
	close(fd);

}

mmap父子进程通信

通过flag参数的调整可以控制信息覆盖。

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/mman.h>
int var=100;
int main(){

	pid_t pid;

	int fd=open("com.txt",O_RDWR|O_CREAT|O_TRUNC,0644);
	ftruncate(fd,10);
	int* m=(int *)mmap(NULL,10,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd,0);
	if(0==MAP_FAILED){
		perror("mmap error!\n");
		exit(1);
	}
	close(fd);

	pid=fork();
	if(0==pid){
		var=1000;
		*m=20;
		
		printf("Son var=%d   m*=%d\n",var,*m);
	}else if(pid>0){
		sleep(1);
		
		printf("Father var=%d m*=%d\n",var,*m);
		munmap(m,10);
	
	}

}

匿名映射(不通过文件传递信息)
flag参数应该为shared 不然没个屌用。

#include<stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/mman.h>

int main(){

	pid_t pid;
	int *p=mmap(NULL,10,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0);

	pid=fork();
	if(0==pid){
		*p=666;
		printf("Son *p=%d\n",*p);
	}else if(pid>0){
		sleep(1);
		printf("Far *p=%d\n",*p);
		munmap(p,10);
	}
}

mmap 无血缘关系进程通信




文件····················




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值