- 消息队列:
- 1、基于内核实现,必须在
内核
空间创建消息队列
; - 2、消息队列中的
消息
由类型
和正文
组成; - 3、消息队列的
默认大小为16KB
; - 运行过程:
- 1、进程1将消息
写入
到消息队列,进程2根据消息的类型
从消息队列中取得对应的消息
; - 2、进程1向消息队列中
发送
消息,可以采用阻塞或者非阻塞
的方式; - 3、进程2从消息队列中
收取
消息,也可以采用阻塞或者非阻塞
的方式; - 常用的接口函数:
- msgget函数:
- 功能:创建或者获取一个消息队列;
c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
/*
参数:
key: 键值
key 通过ftok获取的
IPC_PRIVATE 表示只有亲缘进程间能只用
msgflg:消息队列的标志位
IPC_CREAT|0666 或者 IPC_CREAT|IPC_EXCL|0666
返回值:
成功 消息队列的id
失败 -1 重置错误码
*/
- msgsnd函数:
- 功能:向消息队列中写入一条消息;
c
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
/*
参数:
msqid:消息队列的id
msgp: 要写入的数据的首地址
msgsz:消息正文的大小
msgflg:标志位 0 阻塞发送 IPC_NOWAIT 非阻塞发送
返回值:
成功 0
失败 -1 重置错误码
*/
struct msgbuf {
long mtype; /* 消息的类型 必须大于 0 */
char mtext[1]; /* 消息正文 可以自定义 */
};
- msgrcv函数:
- 功能:在消息队列中读取一条消息;
c
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
/*
参数:
msqid:消息队列的id
msgp: 用来保存接收的数据的缓冲区的首地址
msgsz:消息正文的大小
msgtyp:要接受的消息的类型
0 :接收消息队列中第一条消息
>0 : 接收指定类型的第一条消息
<0 :一般不使用,
表示接收消息队列中第一条类型最小的小于msgtyp的绝对值的消息
3-2-5-500-200-8
读取时,类型传 -200
读取的顺序 2-3-5
msgflg:标志位 0 阻塞接收 IPC_NOWAIT 非阻塞接收
返回值:
成功 实际读到的正文的字节数
失败 -1 重置错误码
*/
struct msgbuf {
long mtype; /* 消息的类型 必须大于 0 */
char mtext[1]; /* 消息正文 可以自定义 */
};
- msgctl函数:
- 功能:控制消息队列;
c
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
/*
参数:
msqid:消息队列id
cmd:指令
IPC_STAT:获取消息队列的属性
IPC_SET:设置消息队列的属性
IPC_RMID:立即删除消息队列
只有消息队列的创建者和所有者以及root用户可以删除消息队列
msgctl函数的第三个参数被忽略
buff:
返回值:
成功 0
失败 -1 重置错误码
*/
- 获取和设置消息队列的属性:
- 属性结构体:
c
struct msqid_ds {
struct ipc_perm msg_perm; /* IPC权限结构体 */
time_t msg_stime; /* 最后一次执行msgsnd的时间 */
time_t msg_rtime; /* 最后一次执行msgrcv的时间 */
time_t msg_ctime; /* 最后一次被修改的时间 */
unsigned long __msg_cbytes; /* 当前消息队列中的字节数 */
msgqnum_t msg_qnum; /* 当前消息队列中的消息数 */
msglen_t msg_qbytes; /* 允许的最大字节数 */
pid_t msg_lspid; /* 最后一次执行msgsnd的进程的PID */
pid_t msg_lrpid; /* 最后一次执行msgrcv的进程的PID */
};
struct ipc_perm {
key_t __key; /* 键值 */
uid_t uid; /* 所属用户的id */
gid_t gid; /* 所属用户的组id */
uid_t cuid; /* 创建者的id */
gid_t cgid; /* 创建者的组id */
unsigned short mode; /* 权限 */
};
- 共享内存:
- 1、同样在
内核
中创建共享内存; - 2、进程1和进程2都能够访问到,通过这段内存空间进行数据的传递;
- 3、共享内存是所有进程间通信方式中,
效率最高
的,不需要在内核中往返进行拷贝
; - 4、共享内存的内存空间大小是
4KB的整数倍
; - 信号灯集:
- 1、实现
进程同步的机制
; - 2、在一个信号灯集中,可以有很多信号灯;
- 3、这些信号灯集中的信号灯
相互独立
,每个灯的值的改变都不会影响到其他的信号灯; - 4、信号灯的值一般设置为
二值量
,即0或者1
,其中0代表没有资源
,1代表有资源
;