IPC 进程间通信 匿名管道 命名管道

本文详细介绍了进程间通信(IPC)的两种常见方式:匿名管道和命名管道。匿名管道用于有亲缘关系的进程通信,而命名管道则允许无关进程间通信。文中通过代码示例解释了管道的创建、读写操作及其特点,并阐述了阻塞与非阻塞模式下读写管道时的情况。
摘要由CSDN通过智能技术生成

IPC(进程间通信):

1、为什么需要通信:因为进程间都是独立的运行空间(内存空间),所。以不能进程间不能直接通信。
2、通信方式:

1、管道:
	匿名管道:
	命名管道:
2、信号:
3、共享内存:
4、消息队列:
5、Socket:

匿名管道

有关系”的进程之间通信(父子进程)
1、创建管道:

#include <unistd.h>
   	int pipe(int pipefd[2]);
形参:
	pipefd[2]:存储的是文件描述符,其中pipefd[0]--读端,pipefd[1]---写端
返回值:
	失败-1,成功0

PS:
1、单向管道,只能一端读,一端写。
2、若某进程同时读写此管道,该管道直接破裂。
3、是一个存放在内存中一个数据结构算法,所以一当进程关闭,此管道丢失败。
4、匿名进程只能应用于关系进程(父子关系)

分析:
父子进程同时保持打开
1、父进程,(已经将写端关闭)保持读端打开;子进程,(已经将读端关闭),保持写端打开,若子进程不写入消息时,父进程当读取管道时,因为管道没有内容则阻塞等待子进程送入消息。
2、父进程,(已经将写端关闭)保持读端打开;子进程,(已经将读端关闭),保持写端打开,若父进程不读取消息,子进程一直写入消息时,若管道为满,子进程会被阻塞等待父进程读取出消息。
父子进程关闭读写端时
3、父进程,(已经将写端关闭)保持读端打开,子进程,(已经将读端关闭),关闭写端,此时,(管道破裂)父进程不会一直等待,将管道中剩余内容读取完成后,就返回0,不再阻塞
4、父进程,(已经将写端关闭)关闭读端,子进程,(已经将读端关闭),保持写端打开,此时,(管道破裂)子进程写入内容时会产生一种信号,此时子进程直接退出(信号)

#include<stdio.h>
#include<sys/wait.h>
void main()
{
	//在创建子进程之间创建
	int fd[2];
	if(pipe(fd)<0)
	{
		perror("pipe fail");
		return ;
	}
	//printf("%d %d\n",fd[0],fd[1]);//fd[0]=3  fd[1]=4
	//创建子进程
	int pid=fork();
	if(pid>0)//父进程:读取信息
	{
		//关闭写入
		close(fd[1]);
		//读取
		/*sleep(10);
		char buf[100]="";
		while(read(fd[0],buf,99)>0)
		{
			printf("收到:%s\n",buf);
		}
		*/
		close(fd[0]);//关闭读端
		sleep(1);
		//等待子进程
		wait(NULL);

		//关闭读取
		close(fd[0]);
	}
	else if(pid==0)//子进程:发送信息
	{
		//关闭读
		close(fd[0]);
		//写入一句话:
		/*
		printf("子进程阻塞3秒,再写入\n");
		sleep(3);
		int i=0;
		while(1)
		{
			i++;
			write(fd[1],"hello father",13);
			printf("子进程一直写入消息 %d\n",i);
		}
		*/
		printf("子进程阻塞3秒,直接关闭\n");
		sleep(2);
		int i=write(fd[1],"hello father",13);
		printf("写内容为%d\n",i);
		//关闭
		close(fd[1]);	
	}
	else 
	{
		perror("fork fail");
	}
}

命名管道:

是一个(FIFO)特殊的文件(路径+文件名)
1、特点:
1、没有关系的进程之间也可以通信
2、FIFO(管道)总是按照先进先出的原则工作,第一个被写入数据首先从管道中读取(底层是通过网络接口)
3、双方没有关闭

无数据可读:

	   read调用会被阻塞,直到有数据来为止(阻塞模式)
	   read调用时会返回-1,errno位置为EAGAIN(非阻塞模式)

管道满:

	write调用时会被阻塞,直到进程读走数据(阻塞模式)
	write调用时返回-1,errno值置为EAGAIN(非阻塞模式)
	
     如果所有写端已经关闭,read返回0
     如果所有读端关闭,write操作会产生信号SIGPIPE信号

2、创建管道:

int mkfifo(const char *pathname, mode_t mode);
形参:
	pathname:路径
	mode:权限
返回值:
	失败-1   errno=EEXIST  文件存在则导致创建失败
	成功0

fifo_send

#include<stdio.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<errno.h>
void main()
{
	//创建命名管道
	int res=mkfifo("./mypipe",0644);	
	if(res<0&& errno!=EEXIST)
	{
		perror("make fail");
		return;
	}
	//操作文件:
	//1、打开文件
	int fd=open("./mypipe",O_WRONLY);	
	if(fd<0)
	{
		perror("open fail");
		return;
	}
	//2、操作(写/读)
	char buf[100]="";
	while(1)
	{
		printf("请输入:");
		scanf("%s",buf);//阻塞
		
		//向管道文件写入内容
		write(fd,buf,strlen(buf));	
	}
	//3、关闭文件
	close(fd);
}




fifo_recv

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{
	//1、打开
	int fd=open("./mypipe",O_RDONLY);
	if(fd<0)
	{
		perror("open fail \n");
		return;
	}
	//2读取
	char buf[100]="1234o";//5 1234
	int ilen=0;
	while((ilen=read(fd,buf,99))>0)
	{
		buf[ilen]='\0';
		printf("收到:%s\n",buf);
	}
	//3关闭
	close(fd);
	
}

执行:
gcc fifo_recv.c -o recv
gcc fifo_send.c -o send
用两个终端分别打开recv和send可以进行单向通信,一个读一个写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值