多进程之管道通信

 

管道通信有两种:无名管道、有名管道

 

无名管道:

无名管道只能作用于亲缘关系的进程,例如父子进程。无名管道其实是数组来的,里面有读端与写端,进程只需要将数据写入/读取到管道中,就可以实现通信。

 

下面是初始化无名管道中的读写端文件描述符

1)申请数组  -> int fd[2];  -> 里面的数据不是文件描述符
2)调用API函数初始化数组          pipe()       man 2 手册
功能: create pipe
使用格式:
#include <unistd.h>

int pipe(int pipefd[2]);

pipefd: 一个具有2个int类型数据的数组
         
返回值:
        成功:0
        失败:-1

3)初始化完毕
pipefd[0]  -> 读端
pipefd[1]  -> 写端

 

实例:

(子进程写入数据,父进程读取并打印出来)

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

int main()
{
	int fd[2]={0};		//资源,会继承给子进程	  f[0]:读  /  f[1]:写
	pipe(fd);
	
	pid_t x;
	x = fork();
	
	if(x > 0)	//父进程
	{
		char buf[10] = {0};
		read(fd[0],buf,sizeof(buf));		//进程执行到这里是阻塞状态,等待子进程写入数据,然后读取
		printf("child to parent:%s\n",buf);
	}
	
	if(x == 0)	//子进程
	{
		char buf[10] = "hello";
		write(fd[1],buf,strlen(buf));
		
	}
	
	return 0;
}

 

有名管道:

无名管道是一个数组来的,而有名管道是文件来的,因为在整个linux系统下,都可以看到这个文件,所以有名管道作用范围是整个linux系统的任意两个进程

 

如何创建有名管道?        mkfifo()        man 3 手册
功能: make a FIFO special file (a named pipe)  -> 创建有名管道
使用格式:
#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);            

pathname:有名管道的路径
mode:八进制权限   0777

      返回值:
    成功:0
    失败:-1

 

实例:

(两.c文件同时运行,写端每次写入数据,读端就会读取数据出来,写入quit时程序结束)

读端:

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

int main()
{
	
	//判断是否有该管道文件,有就返回0,没有就返回-1(非零即是真)
	if(access("/home/gec/fifo",F_OK))
	{
		int ret;
		ret = mkfifo("/home/gec/fifo",0777);		//创建管道文件,八进制权限为0777
		if(ret == -1)
			printf("mkfifo error!\n");
	}
	
	
	//打开管道文件(必须是读写方式打开)
	int fd;
	fd = open("/home/gec/fifo",O_RDWR);		
	if(fd < 0)
		printf("open error!\n");
	
	
	//不断读取管道中内容
	char buf[20];
	while(1)
	{
		bzero(buf,sizeof(buf));
		read(fd,buf,sizeof(buf));
		printf("from fifo:%s\n",buf);
		if(strncmp(buf,"quit",4) == 0)
		{
			break;
		}
		
	}
	
	close(fd);

	return 0;
}

 

写端:

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

int main()
{
	
	//判断是否有该管道文件,有就返回0,没有就返回-1(非零即是真)
	if(access("/home/gec/fifo",F_OK))
	{
		int ret;
		ret = mkfifo("/home/gec/fifo",0777);		//创建管道文件,八进制权限为0777
		if(ret == -1)
			printf("mkfifo error!\n");
	}
	
	
	//打开管道文件(必须是读写方式打开)
	int fd;
	fd = open("/home/gec/fifo",O_RDWR);
	if(fd < 0)
		printf("open error!\n");
	
	
	//不断写入内容进管道中
	char buf[20];
	while(1)
	{
		bzero(buf,sizeof(buf));
		fgets(buf,sizeof(buf),stdin);
		write(fd,buf,strlen(buf));
		
		if(strncmp(buf,"quit",4) == 0)
		{
			break;
		}
		
	}
		

	close(fd);

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值