进程间的通讯方式_管道(有名管道)

当从一个进程连接数据流到另一个进程时,我们使用属于管道(pipe)。我们通常是把一个进程的输出通过管道连接到另一个进程的输入。
(管道是在内存上 开辟出一块空间,不被任何其他进程所占用的)管道包括全双工通讯和半双工通讯。

管道原理:

管道操作:
      有名管道:应用于任意两个进程之间数据的单向传递
      创建:命令方式(mkfifo)、函数方式(mkfifo)
      打开:open
      写数据:write
      读数据:read
      关闭:close
      有名管道是在文件目录树中有一个文件标识(管道文件),实际不占用磁盘空间,数据缓存在内存中。
      与通过 pipe 调用创建管道不同,FIFO 是以命名文件的形式存在, 而不是打开的文件描述符,所以在对它进行读写操作之前必须先打开它。FIFO 也用 open 和 close 函数打开和关闭,这与我们的对文件的操作一样,但它多了一些其他功能,对 FIFO 来说, 传递给 open 调用的是 FIFO 的路径名, 而不是一个正常的文件。 
     
      阻塞运行函数:函数调用后并不会立即返回,需要等待某些条件的发生才会返回,open 操作管道文件时,阻塞运行的函数。
      如果一个进程以只写方式打开一个管道文件,open 会阻塞运行,直到有一个进程以读的方式打开这个管道文件,open 才会返回,进程才会接着执行。
      如果一个进程以只读方式打开一个管道文件,open 会阻塞运行,直到有一个进程以写的方式打开这个管道文件,open 才会返回,进程才会接着执行。
      read 函数也会阻塞运行, 直到写端写入数据或所有写端关闭时返回。
      read 读取数据并且会将内存上的已读数据清空。

练习:A进程负责循环接受用户输入的数据,以“end”为结束标志,B进程负责统计用户输入的单词的个数,显示到界面上。
      首先利用 mkfifo FIFO 命令创建管道文件“FIFO”,如图所示:
      A进程代码如下:
#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);
	assert(fd != -1);
	if (fd == -1)
	{
		exit(0);
	}

	char buffer[128] = {0};
	printf("Please input:");
	fgets(buffer, 128, stdin);

	while (strncmp(buffer,"end",3) != 0)
	{
		write(fd, buffer, strlen(buffer)-1);
		memset(buffer, 0, 128);
		fgets(buffer, 128, stdin);
	}

	close(fd);
	return 0;
}
      B进程代码如下:
#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);
	if (fd == -1)
	{
		exit(0);
	}

	char buffer[128] = {0};
	int count = 0;

	while (read(fd,buffer,127) > 0)
	{
		printf("%s\n", buffer);
		count++;
	}
	printf("count: %d\n",count);

	close(fd);
	return 0;
}
测试运行结果如图所示:



     

猜你喜欢

转载自blog.csdn.net/ylh_yanlinghui/article/details/78314550