IPC

进程状态: 运行, 就绪, 阻塞
Linux下进程状态,运行, 可中断休眠状态, 停止, 僵尸
僵尸状态: 描述的是一个已经退出了但没有完全释放资源的进程的一种状态,这种进程状态称为僵尸状态
产生的原因:子进程先于父进程退出向父进程发送SIGCHLD信号,但是SIGCHLD信号默认的处理方式是忽略处理 ,因此父进程无法直接获知子进程状态
进程僵尸状态危害:资源泄漏;
解决方案: 避免僵尸进程的产生,在父进程创建子进程之后进行进程等待,等待子进程退出,获取返回值,释放子进程资源

程序地址空间: 进程虚拟地址空间
虚拟地址空间的本质: 操作系统通过mm_struct 结构体描述的虚拟空间
虚拟地址空间的优点: 0.每个进程都有虚拟地址空间,提高进程独立性;1.通过页表映射虚拟与物理地址,实现离散式存储,提高内存利用率2.内存访问控制
页表如何实现虚拟地址和物理地址映射:映射关系随着内存管理方式而不同
分段式: 将地址空间分为多个段(正文段, 数据段, 堆, 栈…), 便于地址管理
分段式: 将地址空间分为大量的内存页,进程使用大块连续的虚拟地址,通过页表映射能够实现数据存放在不同的物理内存块上,提高内存利用率
段页式: 先对地址进行分段,在每个分段中进行分页管理
分页式实现:虚拟地址的组+页表
虚拟地址的组成: 页号–对应内存页的编号+ 页内偏移 – 对应数据在页中的偏移量
页表的关键信息: 页号,物理地址…
通过一个虚拟地址中的页号,找到对应的页表中的页表项,进而获取到页表项中对应的物理地址,物理地址加上页内偏移量

进程间通信: 操作系统为用户提供进程间通信方式
操作系统为进程间提供通信的原因: -进程之间具有独立性,每个进程都有自己的虚拟地址空间,访问的都是自己的虚拟地址空间,互补影响,为了让平行进程之间有个交叉点,操作系统为进程之间提供通信方式
进程间通信方式: 管道, 共享内存, 消息队列, 信号量

  • 管道:用于实现进程间的数据进程传输
    本质是内核中的一块缓冲区
    匿名管道: 只能用于具有亲缘关系的进程间通信,子进程复制父进程的方式获取句柄
    在这里插入图片描述

    int pipe(int pipefd[2])管道的操作句柄通过参数返回

    int pipefd[2] = {-1};//pipefd[0]读端 pipefd[1]写端
    int ret = pipe(pipefd);
    if(ret < 0){
    perror("pipe error");
    return -1;
    }
    pid_t pid = fork();
    if(pid == 0){//fork()返回值为0--子进程
    ....
    }
    else if(pid > 0){//父进程得到子进程的pid号
    ...
    }
    

    管道的特性:
    1.半双工通信–单方向上的通信
    2.管道自带同步与互斥:
    互斥:通过同一时间的唯一访问,保证本次访问的安全
    管道每次操作,操作大小不超过PIPE_BUF大小,保证操作的原子性
    同步:按照某种秩序进行访问,保证访问的合理性
    管道的数据满了的时候继续write就会阻塞进程;管道中没有数据继续read就会阻塞
    互斥保证同一时间唯一访问,确保访问安全,同步按照秩序进行访问,确保访问合理
    3.管道提供字节流服务
    提供有序定的, 安全的, 基于连接的, 可靠的以字节为单位的传输方式
    连接的:管道的所有读端被关闭了,则write就会触发异常,进程退出; 所有写端被关闭,则read读取完管道中的所有的数据后就会退出,不会阻塞而是返回0
    4.管道的生命周期随进程

命名管道:int mkfifo(char *filename, mode_t mode)
命名管道的本质也是内核中一块缓冲区,这块缓冲区有标识就是一个可见于文件系统的管道文件
多个进程打开同一个管道文件,访问的是同一块内核中的缓冲区,进而实现通信

  • 共享内存:
    本质原理: 开辟一块共享内存(一块物理内存, 并且在内核中进行了各种描述–名字–标识符)多个进程通过相同的标识符,找到相同的一块物理内存,将其映射到自己的虚拟地址空间中,通过自己的虚拟地址空间进行访问,最终实现通信
    在这里插入图片描述操作流程:
    1.创建/打开共享内存 int shmget(key_t key,int size,int flag);//key-标识符;size-大小;flag-权限
    2.与共享内建立映射关系 int shmat(int shmid,void *addr,int flag)//shmid共享内存id
    3.内存操作(mecopy之类的内存操作)
    4.解除映射关系int shmdt(void *addr)//解除映射关系不代表删除共享内存
    5.删除共性内存int shmctl(int shmid,int cmd,struct shmid_ds *buf);通常是将共享内存删除,最后的buf置为空
    共享内存的特性:
    1.最快的进程间通信方式(相较于其他的方式少了两步用户态到内核态的数据拷贝的操作)
    2.共享内存的生命周期随内核
    注意事项: 共享内存的操作并非是安全的,当前一个进程写入,第二个进程在进行写入时就会造成数据写入的冲突

  • 消息队列: 本质是内核中的一个优先级队列,多个进程通过相同的标识符访问同一个队列
    特性: 生命周期随内核,自带同步与互斥

  • 信号量: 实现进程间的同步与互斥
    本质原理是一个计数器,统计资源的数量,在有资源的情况下才能够进行访问,实现资源访问的合理性(通过资源计数来进行判断: 有资源的时候才能获取,没有资源的时候就等着)
    信号量的操作:P/V操作
    P操作:计数-1,判断是否小于0,小于0,表示没有资源,则进程等待
    V操作:计数+1,判断有没有进程等待,如果有等待的进程,则唤醒一个
    信号量实现互斥: 同一时间对资源的唯一访问
    信号量实现互斥的原理: 保证资源数只有一个,这时只有一个进程能够进行访问,访问完毕之后计数还原
    信号量实现同步:信号量的主要目的是用来实现同步的,通过计数进行资源获取的合理性判断(计数大于0能访问,计数小于0不能访问,这就是合理的访问秩序)
    进程通信是什么?
    为什么要进行进程间通信?
    因为每个进程是具有独立性,无法直接进行通信,所以操作系统为程序员提供的进程间通信方式,以针对不同的应用场景;
    方式分类:管道,共享内存,消息队列,信号量
    不同方式的本质以及提供的功能:
    内核中的缓冲区
    一块共享的物理内存
    内核中的一个优先级队列
    一个对资源的计数器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值