进程间通信----管道

进程间通信

了解管道之前,我们先要了解什么是进程间通信,为什么要进程间通信,进程间通信有什么好处,以及有哪些进程间通信方式!

背景:
1.在很多情况下,一些大型的程序使用的是多个进程相互配合完成任务
2.但是 进程具有独立性 ,无法方便的进行进程之间的沟通
3.为了使多个进程能容易的进行进程间的交流,引出进程间通信

作用:
1.数据交换
2.资源共享
3.相互通知
4.进程控制:某些进程需要被另一个进程完全控制

分类:
古老 的方式:
管道(pipe):匿名管道、命名管道
System V IPC标准:消息队列、共享内存、信号量
POSIX PIC标准:消息队列、共享内存、信号量、互斥量、条件变量、读写锁

管道

匿名管道:

1.实质:操作系统内核中的一块内存

2.操作方法:本着Linux中一切皆文件的原则,于是乎采用文件I\O的方式操作管道

父子进程实现单向通信代码:

#include<stdio.h>             
#include<unistd.h>            
#include<string.h>            
#include<errno.h>             
                              
int main(){                   
    int fd[2];                
    if(pipe(fd) < 0){         
        perror("pipe error"); 
        return -1;            
    }                         
	
    pid_t pid = fork();       
    if(pid < 0){              
        perror("fork error"); 
        return -1;            
    }                         
    if(pid == 0){             
        //child  close write  
        close(fd[1]);         
        char buf[1024] = {0}; 
		read(fd[0], buf, sizeof(buf) -1);
        printf("buf = %s\n",buf);        
        close(fd[0]);                    
    }                                    
    else{                                
        //father close read              
        sleep(2);                        
        close(fd[0]);                    
        char msg[] = "xixixhahahzhoudaxinbalalala"; 
        write(fd[1], msg, strlen(msg));             
        close(fd[1]); 
    }  
	return 0;	
}             

在这里插入图片描述

在这里插入图片描述
3.创建管道:
int pipe(int fd[2]);
返回值:成功0,失败错误码
参数: fd[2] 文件描述符数组
fd[0] 表示读(从管道中读取内容)
fd[1] 表示写(将内容写入管道当中)
通过操作该文件描述符数组操作管道(也就是管道所对应的内存)
失败原因:
管道资源(内存资源)不足
文件描述符达到上限

求一个进程可以申请的最大管道数代码:

#include<stdio.h>     
#include<unistd.h>    
#include<string.h>    
#include<sysexits.h>  
int main(){           
  int count = 0;      
  while(1){           
    usleep(40000);    
    int fd[2] = {0};  
    int ret = pipe(fd);
    if(ret < 0){       
      printf("i can pipe %d times\n", count);
      perror("pipe!!");                      
      break;                                 
    }                                        
    else{                                    
      printf("this is %d pipe\n",count);     
    }            
    count++;     
	}         
    return 0;    
}   

结果展示:
在这里插入图片描述
4.管道读写规则:
a.管道为空:read调用阻塞
b.管道已满:write调用阻塞
c.写端关闭:read返回0
d.读端关闭:write错误退出(产生SIGPIPE信号)
c.写入数据小于管道内存大小:写入操作保证具有原子性,反之则不保证具有原子性

注:原子性表示该操作不会被打断,直接完成。

命名管道:
1.实质:本体仍是内核中的一块内存
一种特殊类型的文件(文件系统可见)(该文件是管道入口)

2.操作方法:通过文件I\O操作管道

3.创建管道文件:
a.命令行创建
mkfifo filename 创建管道入口文件
b.代码创建
int mkfifo(const char filename, mode_t mode);
filename: 文件名称
mode: 文件权限

4.打开规则:
用open打开
读、写需要 同时打开,否则会阻塞
通过采用只读方式打开:得到读取管道内容的文件描述符
通过采用只写方式打开:得到将数据写入管道的文件描述符

匿名管道和命名管道的区别:
匿名管道只能用于具有亲属关系的管道之间,命名管道用于任意管道之间
匿名管道打开方式是pipe函数,命名管道打开方式是open

管道总结:
a. 匿名管道 只能用于具有亲属关系的进程之间通信 命名管道 用于任意进程之间
b.管道传输面向字节流,收发数据灵活,数据无规则发送,数据无边界
c.管道生命周期随进程,进程结束,管道释放
d.内核对管道操作进行同步和互斥
e.管道是半双工单向通信,数据只有一个流向
f.本质上都是操作系统内核中的一段内存

关于管道的内容到此结束,谢谢大家的支持!!
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值