消息队列
消息队列的结构有很多,但在这里讲的队列的结构都是基于链表实现的.
进程间通信的实质是:让不同的进程可以看到相同的资源. |
消息队列的特点:
- 消息队列的通信是通过发送有类型数据块的方法.
- 每个数据块都有一个类型,接收方接受的数据块可以有不同的类型值.
- 消息队列的最大长度有限制.(缺点,因为消息队列必定要占用内存,而如果只发送不接受就会耗内存.)
所以:消息队列提供了一个进程向另一个进程发送了有类型数据块的方法.
实现消息队列的相关函数:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
函数作用:为创建消息队列的函数提供参数.
注意:对于这个函数,若函数的参数相同,则函数的返回值相同.
①创建消息队列的函数:
int msgget(key_t key,int msgflg);
msgflg:与文件的权限mode是相同的.
常用的参数有:
IPC_CREAT:不存在就创建,若存在就打开.
IPC_EXCL:若存在,就失败.与上面的搭配使用.
函数创建成功就返回非负整数
②消息队列控制函数
int magctl(int msqid,int cmd,struct msqid_ds *buf);
参数:
msqid_ds:表示消息队列
cmd:函数执行的作用:IPC_RMID(删除消息队列)
函数返回值:成功返回0失败返-1;
③把消息添加到消息队列中
int msgsnd(int msqid,const void* msgp,size_t msgsz,int msqflg);
④从一个消息队列中接收消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msgp:指向接受的消息的队列.
msgsz:消息队列的长度.
msgtyp:可以实现接收优先级.若为0,就是普通的队列.
查看消息队列的指令:ipcs -q 手动删除某个消息队列:ipcrm -q 进程id |
总结消息队列: 1. 全双工的通信方式. 2. 面向数据块. 3. 内置同步互斥机制. 4. 声明周期随内核.(可以通过手动删除和重启来删除一个消息队列). 5. 可以用于任意进程. |
共享内存
每个进程都有自己的虚拟内存空间,而物理空间只有一份,当多个进程映射到相同的物理地址后,那么就可以共同访问这块内存.即共享内存.
蹦蹦蹦:共享内存是最快的进程间通信的方式(省略了两次内存拷贝).但是同时也是不稳定的,由于共同访问同一块内存,会产生不可预知的错误.
实现共享内存调用的相关函数:
int shmget(key_t key,size_t size,int shmget);
key:共享内存段的名字.
size:共享内存的大小.(按页的大小向上取整.一般而言页的大小为4K)
shmflg:与消息队列的那个参数相同.
void* shmat(int shmid,const void* shmaddr,int shmflg);
shmaddr:共享内存连接的地址.
成功返回一个指向共享内存的第一个指针,失败返回-1.
int shmctl(int shmid,int cmd,struct_ds *buf);
cmd:与消息队列中的那个参数相同.
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构.
总结共享内存: 1. 双向通信全双工. 2. 用于任意进程间的通信方式. 3. 不存在”面向数据报”和”面向字节流”. 4. 没有同步互斥机制. 5. 生命周期随内核. |
扫描二维码关注公众号,回复:
1622249 查看本文章
信号量
为什么要有信号量的通信方式? 消息队列,共享内存以及管道都是可以同时又多个进程去访问公共资源,可能会引发一系列的问题.而信号量是为了通过控制其他的通信的公共资源来实现进程间通信.信号量则会负责数据操作的同步,互斥等. |
信号量的同步指的是所有的进程按照一定的顺序去执行任务,实现对资源的有序访问.
信号量的互斥指的是当有一个进程在临界区时,其余的进程只能等待,等待那个进程出了临界区.
信号量的PV操作
这里的信号量指的是二元信号量,非0即1.
P操作:申请使用临界资源,信号量减一;
V操作:释放临界资源,信号量加一.
注意:消息队列,共享内存以及信号量都是基于system V版本的进程间通信的方式.