linux系统编程-进程间通信-无名管道(pipe)

 

linux系统编程-进程间通信-有名管道(mkfifo)

无名管道实现通信:

只能用于具有亲缘关系之间的通信,及就是父子进程间通信。管道通信来自于继承,通信基于文件描述符。

管道有固定的读段和写段fd[0]和fd[1];只能单向通信,一边进一边出,可实现半双工通信。

管道像文件,但是不是文件,它是一段特殊的内存,在kernelSpace中。当通信结束之后则就不可见。

既然管道像文件,则它的操作可以使用文件的IO来操作,当管道为空时,则读会阻塞,则写也会阻塞。

平时提到的,代码段数据。。。。这是UserSpace 占据了3-4G.另外的是kernelSpace的空间,属于公用空间。这两个都是虚拟内存。内存条是物理内存。

物理内存和虚拟内存需要在进程中经过映射,获取更大的内存。当物理内存使用完,则就无法完成映射,获取新的映射内存。

物理假设0-8G,一般说进程的内存是0-4G

因为就时一段内存,在系统之中是不可见的,没办法区表示它,因此叫无名管道。

如何使用管道进行通信:

  1. 创建父进程、并且创建管道
  2. 创建子进程,用来实现并发
  3. 在父进程中关闭读段或写段,假设:父进程中关闭读段,只保留写段,写数据中到管道,使用完毕后关闭管道
  4. 在子进程中关闭读段或写段,假设:在子进程中关闭写段,只保留读段,读取buff中的内容,当读取数据后,关闭管道。
  5. 相关函数:

创建并且打开管道:int pipe(int fd[2]);当创建成功之后会通过参数返回两个int fd[2]的值。当成功的返回 0 ;

fd[0]代表读段  fd[1] 表示写端

 

注意事项:

当管道中无数据是,则读操作阻塞

向管道中写入数据是,linux将不保证写入的原子性,(不保证内容有序性),管道缓冲区一有空闲区域,写进程就会试图向管道写入数据,如果读进程不读走管道缓冲区中的数据,那么写操作将会一直阻塞。

只有在管道的读段存在时,向管道中写入数据才会有意义,否则,向管道中写入数据,的进程将会收到SIGPIPE通常会 Break pipe错误。

例程

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

#define DATA_LEN 256
#define DELAY_TIME 1


int main()
{

	int fd[2]={0};
	pid_t pid;
	char buf[DATA_LEN];
	const char data[]="pip test program";
	int read_Num,write_Num;
	
	
	if(pipe(fd)<0)
	{
		perror("创建管道失败\n");
		exit(-1);
	}

	pid = fork();
	if(pid == 0)//创建子进程会返回值 0
	{
		close(fd[1]);
		sleep(2);
		read_Num = read(fd[0],buf,DATA_LEN);
		if(read_Num > 0)
		{
			printf("子进程中读取的内容 %s\n",buf);
		}
		close(fd[0]);
		exit(0);		
	}else if(pid > 0)//进入父进程
	{
		close(fd[0]);
		sleep(2);
		write_Num = write(fd[1],data,strlen(data));
		if(write_Num > 0)
		{
			printf("父进程写入的数据: %s\n",data);
		}
		close(fd[1]);
		waitpid(pid,NULL,0);
		exit(0);
	}
	return 0;
}

 

 

 

猜你喜欢

转载自blog.csdn.net/yuupengsun/article/details/106290500