进程间通信:管道(IPC InterProcess Communication)

进程间通信是指在不同进程之间传播或交换信息。

IPC的方式有:管道(有名管道、无名管道)、信号量、共享内存、消息队列、套接字。

管道

通常指无名管道是NUIX系统IPC最古老的形式。和普通文件最大的区别:写入的文件在内存中

特点:1、半双工(同一时刻数据只能在一个方向上流动),具有固定的读端和写端。

           2、写管道的数据在内存中。

           3、有有名管道和无名管道区别,有名管道在任意两个进程之间通信,无名管道只能在父子进程之间通信。

无名管道是通过pipe函数创建的

#include <unistd.h>
    int pipe(int fd[2]);
    返回值:成功0,失败-1

当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开

如果要求数据从父进程流向子进程,则关闭父进程读端,关闭子进程写端。如下图

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


int main()
{
    int fd[2];
    assert(pipe(fd)!=-1);

    pid_t pid = fork();
    assert(pid!=-1);

    if(pid == 0)
    {
	close(fd[1]);//子进程读,关闭写fd[1]
	while(1)
	{
	    char buff[128]={0};
	    if(read(fd[0],buff,127)==0)// 将fd[0]所指的文件,读127个字节,放入buff中,然后输出
	    {
		break;
	    }
	    printf("child read:%s\n",buff);
	}
	close (fd[0]);
	exit(0);

    }
    else
    {
	close(fd[0]);//父进程写 关闭读fd[0]

	while(1)c
	{
	    char buff[128]={0};
	    fgets(buff,128,stdin);//从输入流中读取128个字节到buff
	    if(strncmp(buff,"end",3)==0)
	    {
		break;
	    }
	    write(fd[1],buff,strlen(buff));//buff所指的文件写strlen(buff)个字节到fd[1]所指的文件中
	}
	close(fd[1]);
	exit(0);
    }

}

FIFO有名管道也称命名管道,是一种文件类型

FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据,并且“先进先出”。要同时打开一读一写

管道为空,写端没有关闭,read阻塞

写端关闭,读端的read返回0 

1、两者区别

有名管道可以在任意两个进程之间通信。mkfifo

无名管道只能在父子进程之间通信。Pipe()

2、写入管道的数据在内存中存放(有名管道 无名管道)   磁盘上存放的是属性信息,属性和数据是分开存储

3、通讯方式:半双工(单工 半双工对讲机 全双工)

4、程序有关:管道为空,写不会阻塞,读操作会阻塞(可以设置非阻塞,这时直接返回错误-1)管道满,写阻塞,读操作不会阻塞。空间还有多少写多少。

操作管道,读端和写端都必须存在。

           如果写端关闭,读返回0(意思是读到0个字节),也不会阻塞

           如果读端关闭,写会产生异常SIGPIPE 程序退出

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

int main()
{
    int fd= open("fifo",O_WRONLY);//只写  fd为文件描述符,以写的方式打开fifo
    assert(fd !=-1);

    printf("fd=%d\n",fd);

    while(1)
    {
	char buff[128]={0};
	printf("input\n");


	fgets(buff,128,stdin);
	if(strncmp(buff,"end",3)==0)
	
	{
	    break;
	}
	write(fd,buff,strlen(buff));
    }
    close(fd);
    exit(0);
}

    


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


int main()
{
    int fd = open("fifo",O_RDONLY);//只读
    assert(fd !=-1);
    printf("fd=%d\n",fd);
    while(1)
    {
    
    char buff[128]={0};

    int n = read(fd,buff,127);
    if(n==0)
     {
	break;
     }
    printf("n=%d\n buff=%s\n",n,buff);
    }
    close(fd);
    exit(0);

 }

管道是怎么实现的

实现:

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值