Linux进程间通信(2)---无名管道和有名管道(超简单,有示例程序)

管道是什么呢?

比如说有两个池塘A和B如果我先要A和B中的水可以相互流动,那么我们只需要在两个池塘间安放一条水管就可以了嘛!如果将A、B换成我们程序中的进程,那么使这两个进程通信的那根管子就叫管道。


管道可以分为两种:
无名管道:用于父子进程间的通信。
有名管道:用于任意两进程间的通信。

首先我们来看一下无名管道

管道不是有两端嘛,每一端都可以流入水和流出水,但是流入和流出是不是只能有一种情况呢。所以在无名管道中也一样,无名管道的两端,每一端都可以读和写。
若一端为读就要关闭他的写功能,另一端就只能为写关闭读功能
下面我们先看一下一个函数

#include <unistd.h>
int pipe(int pipefd[2])
作用:创建一个无名管道
参数:pipefd[2]为你自己定义的一个数组
返回值:成功 0,失败 -1;
pipefd[0]存储管道的读描述符
pipefd[1]存储管道的写描述符

好了接下来无名写一个小程序:

/*
创建一个管道,子进程读取管道内容,父进程写入管道内容
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define N 1024
/*
  1、子进程读 父进程写
  2、先写才能读,所以保证父进程先完成写操作
*/
int main(void)
{
pid_t pid;
 int pipe_fd[2];
 int fd;
 char date[]="wlecome the rose flower shop";
 char buf[N];
 if(pipe(pipe_fd)<0)
 {
   printf("pipe error\n");
 }
 pid=fork();
if(pid==0)//子进程
{
 close(pipe_fd[1]);//子进程用于读,所以关闭写功能
 sleep(3);//保证父进程运行完成,子进程只执行到关闭写功能
 fd= read(pipe_fd[0],buf,sizeof(date));
 if(fd>0)
 {
 printf("child progress read: %s\n", buf);
 }
 close(pipe_fd[0]);
 exit(0);
}
if(pid>0)
{
 close(pipe_fd[0]);//父进程写入,所以关闭读功能
 sleep(1);//等待子进程关闭写功能
 fd=write(pipe_fd[1],date,sizeof(date));
 if(fd>0)
 {
 printf("father progress write: %s\n", date);
 }
 close(pipe_fd[1]);
 sleep(2);
}
 return 0;
}
/*
子进程:
 close(pipe_fd[1]);
 sleep(3);
 父进程:
  close(pipe_fd[0]);
 sleep(1);

原因:假如子进程先运行(fork创建的进程父、子进程无法判断谁先运
行)子进程是读所以关闭写,sleep(3)让父进程运行,此时父进程运行,
先关闭读功能,还要保证写功能没有被子进程占用,这里子进程先运行上
来就关闭子进程的写功能了。假如父进程先运行,父进程先关闭读功能,
但是子进程没有关闭写功能,所以父进程sleep(1)延时1S.让子进程执行
完第一条程序。sleep(1)<sleep(3)
*/

看一下运行结果:
在这里插入图片描述
2s后
在这里插入图片描述

有名管道

有名管道你就可以理解为,有一个文件,A、B进程都可以访问,A可以向里面写数据,也可以读数据,B亦然。

话不多说,我们先来看一个函数

#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char * pathname,mode_t mode);
参数:pathname: 文件名
          mode:这个要深入研究的话比较复杂,我网上查了也很多
 https://blog.csdn.net/superywf/article/details/73438465
这个博客里面是这样说的:
mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而
参数mode为该文件的权限

有名管道读端:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define MYFIFO "/zxp_linux/myfifo"
int main(void)
{
  int fd;
  char buff[4096];
  if(access(MYFIFO,F_OK)==-1)//检测文件是否存在,函数详解可以csdn一搜就有
  {
	    if(mkfifo(MYFIFO,0666)<0)//创建有名管道
		{
		printf("error mkfifo\n");
		exit(1);
		} 
  }
  fd=open(MYFIFO,O_RDONLY);//打开有名管道(文件)
  if(fd<0)
  {
  printf("error open\n");
  exit(1);
  }

  while(1)
	   {
	   memset(buff,0,sizeof(buff));
	   if(read(fd,buff,sizeof(buff)))
		    {
			printf("read named_pipe %s\n", buff);
			}
	   
	   }
close(fd);
return 0;
}

写端口:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define MYFIFO "/zxp_linux/myfifo"
int main(int argc,char *argv[])
{
int fd;
char buff[4096]={0};
 if(argc<=1)
	  {
	  printf("error scanf\n");
	  printf("./write string\n");
	  }

 sscanf(argv[1],"%s",buff);
fd=open(MYFIFO,O_WRONLY);
if(fd<0)
{
 printf("error open\n");
 exit(1);
}
if(write(fd,buff,sizeof(buff)));
 {
  printf("pipe write %s\n", buff);
 }
close(fd);
return 0;
}

运行结果:
在这里插入图片描述

本文代码参考博客:
http://blog.csdn.net/mybelief321/article/details/9073895
https://blog.csdn.net/mybelief321/article/details/9075229

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值