进程间通信 IPC 概述

Linux进程间通信,大致有五种
原始的信号和管道,还有共享内存,消息队列和信号。

1. 管道

管道分为两种 pipe和fifo
pipe可用有亲缘关系的进程,比如父子进程,兄弟进程
fifo可用不同进程之间,不限于亲缘关系

pipe

半双工,一端读一端写,数据在一个方向上流动。可以看成是一种特殊的文件,只不过它只在内存里,不落地到文件系统。
管道的缓冲区有限制,PIPE_BUF 一般是一个页面的大小,管道传输的无格式字节流,这就要求读写双发要实现约定好数据格式。它没有名字,所以只能在亲缘关系进程之间使用。

fifo

一种特殊文件,落地到文件系统。严格支持先进先出。
int mkfifo(const char * pathname, mode_t mode)

2. 信号

信号,一个进程向另一个进程发送很简短的信号,通知某个事情。
信号在signal.h中有定义,SIG开头的都是信号。
这里要重点掌握两个函数

  • signal
  • sigaction 专业
    sigaction的优势在于,在调用它之前,可以设置信号屏蔽字可以防止信号在它的处理函数还未运行结束时就被接收到的情况。
    还有两个发送信号的函数
  • kill
  • alarm

3. 共享内存

共享内存,可以允许两个以上的进程同时访问一个块内存。这个内存实际上是在内核态中的,进程使用时,会映射到进程的地址空间中。

主要函数

  • shmget 创建或者打开共享内存
    int shmget(key_t key, size_t size, int shmflg);
  • shmat 把共享内存映射过来
    void *shmat(int shm_id, const void *shm_addr, int shmflg);
  • 解除映射
    int shmdt(const void *shmaddr);
  • 控制共享内存
    int shmctl(int shm_id, int command, struct shmid_ds *buf);
    命令选项
    IPC_STAT 设置共享内存访问权限
    IPC_SET 设置共享内存访问权限
    IPC_RMID 删除共享内存

4. 消息队列

消息队列,是消息的链表,存放再内核中,有一个标识符(队列id)标记(其实就是ipc id, 这里ipc指的是system v ipc ,其实共享内存和信号也都有这个id)。
写权限的进程可以往消息队列中添加消息
具有读权限的进程可以从消息队列中读取信息。
又因为它在内核中,所以多进程之间可以访问,在进程结束时,消息队列不会被清除。
可按照类型随机查询,并不一定要按先进先出的次序读取。
消息: 定长消息头+变长消息正文

  • msgget//创建或者打开一个消息队列
  • msgsnd
  • int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long
    mtype,
    int msgflg )
    mtype 如果mtype 的值是零的话,函数将不做类型检查而自动返回队列中的最早的消息
  • msgctl //操作消息队列

5. 信号量

信号量其实有点不同,是用来保持进程之间互斥和同步,而不是共享数据的。它提供一种访问机制,让一个临界区只能由x个进程来访问。它是一种特殊的变量,程序对其访问都是原子操作,由两种操作,一种时等待P,另一种时发送V

  • P(sv): 当sv>0时,sv-1,向下执行;当sv=0时,挂起
  • V(sv): 当系统由因为等待sv而挂起的进程时,使其执行;如果没有,sv+1

信号量三个函数

  • semget 打开和创建一个信号量
  • semop 信号量P V操作
  • semctl 信号量初始化,删除操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值