进程间通讯方式:管道(一)-------有名管道

    我们知道,进程之间的栈区,堆区的数据及全局或静态变量都是不共享的。而往往很多时候进程间是需要信息共享的,进程间通讯的方式不止一种,其中有一种通讯方式叫“有名管道”。

    顾名思义,有名管道是有名字的。但是呢,有名管道仅仅是在目录树中存在一个文件标识,并不会占据磁盘空间。所以不同的进程操作同一个管道文件实际上是在操作同一块内存。

    如何创建,使用有名管道呢?(以下内容均在linux系统下实现)

    创建:

                有两种创建方式:1、使用命令mkfifo+filename

                                           2、代码创建,函数int mkfifo(char *path,int mode);


    使用:

                这里实现以下任务:a进程接受用户输入的数据,把数据传给b进程,b进程把输入的大写字母转成小写字母再传回给a进程,a进程最后输出b进程处理后的数据。

                这里我们先用命令创建了两个有名管道文件“FIFO”“FIFO1”;

                

               由于管道通讯是“半双工通讯”,即两个进程既可以是写端也可以是读端,但同一时刻,信息只能有一个传输方向。所以创建两个管道,大概的思想就是,a进程数据写入FIFO,b进程从FIFO读,b进程处理过的数据写入FIFO1,a进程从FIFO1再读。

                这是a进程的代码

	char tmp[MAXLEN]={0};
	int fd1 = open("FIFO",O_WRONLY);
	int fd2 = open("FIFO1",O_RDONLY);
	if( fd1 == -1 || fd2 == -1 )
	{
		perror("fd");
		exit(0);
	}
	while(1)
	{
		printf("please input:");
		fgets(tmp,MAXLEN-1,stdin);
		write(fd1,tmp,strlen(tmp)-1);
		if( strncmp(tmp,"end",3) ==0 )
			break ;
		memset(tmp,0,MAXLEN);
		read(fd2,tmp,MAXLEN);
		printf("result:%s\n",tmp);
	}
	close(fd1);
	close(fd2);

             这是b进程的代码

	char tmp[MAXLEN] = {0};
	int i  ;
	int fd1 = open("FIFO",O_RDONLY);
	int fd2 = open("FIFO1",O_WRONLY);
	if( fd1 == -1 || fd2 == -1 )
	{
		perror("fd");
		exit(0);
	}
	while(1)
	{
		int co = read(fd1,tmp,MAXLEN);
		if( co == 0 || strncmp(tmp,"end",3) == 0 )
			break;
		for( i = 0 ; i < co ; ++i )
		{
			if( isupper(tmp[i]) )
				tmp[i] = tmp[i] - 'A' + 'a';
		}
		write(fd2,tmp,strlen(tmp));
		memset(tmp,0,MAXLEN);
	}
	close(fd1);
	close(fd2);

            当我们编译成功后单独运行a时发现a并没有打印"please input:",证明此时还没执行到循环里,那是为什么呢?        

            

            当我们把b也运行起来,发现a打印了"please input:",此时已进入循环等待用户输入。

            

            

            

            接着

            

            我们发现程序执行没有问题,可是read函数不是应该不阻塞的吗,到这里却乖乖地一写一读。

            所以我们再总结一下管道通讯的特点:如果一个进程以只读打开一个管道文件,open会阻塞,直到另一个进程以写打开;如果一个进程以只写打开一个管道文件,open会阻塞,直到另一个进程以读打开。read函数也会阻塞,直到有进程向管道里面写入数据或写端关闭。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页