多进程间通信学习之无名管道

  • 无名管道:
  • 首先它是内核空间的实现机制;
  • 然后只能用于亲缘进程间通信
  • 它在内核所占的大小是64KB
  • 它采用半双工的通信方式;
  • 请勿使用lseek函数
  • 读写特点:
  • 若读端存在写管道,那么有多少数据,就写多少数据,直到无名管道写满为止,此时会出现写阻塞,当无名管道出现新的4KB空间,写操作就会解除阻塞;
  • 若读端不存在写管道,会出现管道破裂的情况;
  • 若写端存在读管道,那么有多少数据,就读多少数据,没有数据的时候,会出现阻塞等待
  • 若写端不存在读管道,有多少数据,就读多少,没有数据的时候,就会立即返回,即非阻塞的状态;
  • 创建无名管道(pipe函数):
	#include 
	
	int pipe(int pipefd[2]);
	/*
	功能:
	
		创建一个管道,是一个单向的数据通道,可用于进程间通信
	
		数组pipefd返回两个指向管道的文件描述符:
	
			pipefd[0]指向管道的读端 
			pipefd[1]指向管道的写端
	
		写入管道的数据被内核缓冲(64KB),直到从管道中读走
	
	参数:
	
		操作管道的文件描述符数组 
	
		pipefd[0]指向读端 pipefd[1] 指向管道的写端
	
	返回值:
	
		成功 0
	
		失败 -1 重置错误码
	*/ 
  • 实例要求:
  • 创建一个进程,要求使用无名管道,实现父进程写子进程读的操作;
  • 示例代码:
	#include 
	#include 
	#include 
	
	#include 
	#include 
	
	#include 
	#include 
	
	int main(int argc, char const *argv[])
	{   
	    int pipe_fd[2] = {0};
	    if(-1 == pipe(pipe_fd))
	    {
	        perror("pipe error");
	        exit(-1);
	    }
	
	    pid_t pid = 0;
	    if(-1 == (pid = fork()))
	    {
	        perror("fork error");
	        exit(-1);
	    }
	    else if(0 < pid) //父进程写
	    {
	        close(pipe_fd[0]);
	        char buf[128] = {0};
	        while(true)
	        {
	            fgets(buf,sizeof(buf),stdin);
	            buf[strlen(buf) - 1] = '\0';
	            write(pipe_fd[1],buf,sizeof(buf));
	            if(!strncmp(buf,"quit",4))
	            {
	                exit(-1);
	            }
	        }
	        sleep(2);
	        wait(NULL);   //回收子进程的资源
	
	    }
	    else if(0 == pid) //子进程读
	    {
	        close(pipe_fd[1]);
	        char buf[128] = {0};
	        while(true)
	        {
	            memset(buf,0,sizeof(buf));
	            read(pipe_fd[0],buf,sizeof(buf));
	            if(!strncmp(buf,"quit",4))
	            {
	                close(pipe_fd[0]);
	                exit(-1);
	            }
	            printf("父进程发来的消息[%s]\n",buf);
	        }
	
	    }
	    
	    return 0;
	}

  • 运行结果:
	linux@ubuntu:~$ gcc pipe.c 
	linux@ubuntu:~$ ./a.out 
	hello beijing
	父进程发来的消息[hello beijing]
	i love china
	父进程发来的消息[i love china]
	quit
	linux@ubuntu:~$ 
  • 总结:
  • 为了防止误操作,在父进程和子进程里,分别关闭读端和写端;

你可能感兴趣的:(多进程间通信学习系列,学习,算法,linux,无名管道,c语言,运维)