sgtype > 0 - 若msgflg参数不包含MSG_EXCEPT位,则返回消息队列中第一个类型为msgtype的消息
如果msgflg参数包含MSG_EXCEPT位,则返回消息队列中第一个消息类型不为msgtype的消息
msgtype < 0 - 返回消息队列中类型小于等于msgtype绝对值的消息
如果有多条消息满足,则返回消息类型最小的第一条消息
G.若消息队列中有可接收的消息,则此函数会将该消息移出消息队列拷贝到msgp内存中并立即返回0,表示接收成功
如果消息队列中没有可接收的消息,则此函数会阻塞,直到消息队列中有可接收的消息为止
H.如果msgflg参数包含IPC_NOWAIT位,则当消息队列中没有可接收的消息时(没有满足要求的消息),则此函数不会阻塞,而是返回-1,设置errno为ENOMSG
成功返回所接收到消息数据的字节数,失败返回-1
*/
//msgctl销毁/控制消息队列
int msgctl(int msgqid,int cmd,struct smqid_ds *buf);
/*
cmd的取值:
IPC_STAT - 获取消队列的属性,通过buf参数输出
IPC_SET - 设置消息队列的属性,通过buf输入
msg_perm.uid
msg_perm.gid
msg_perm.mode
msg_qbytes
IPC_RMID - 立即删除消息队列
此时所有阻塞在该消息队列的,msgsnd/msgrcv函数调用都会立即返回失败,errno设置为EIDRM
成功返回0 失败返回-1
*/
struct msqid_ds{
struct ipc_perm msg_perm; //权限依赖
time_t msg_stime; //最后发送时间
time_t msg_rtime; //最后接收时间
time_t msg_ctime; //最后修改时间
unsigned long _msg_cbytes; //消息队列中的字节数
msgqumt_t msg_qnum; //消息队列中消息数
msglen_t msg_qbytes; //消息队列能容纳的最大字节数
pid_t msg_lspid; //最后发送消息进程ID
pid_t msg_lrpid; //最后接收消息进程ID
};
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; //权限
unsigned short __seq;//序列号
};
#ipcs -q # 查看消息队列
#ipcrm -q msqid # 删除指定的消息队列
信号量
基本特点
- 本质上是用于限制对于共享资源访问的进程数量 计数器
- 计数器如果设置为1,表示任意时刻只允许一个进程对共享资源进行访问 文件锁写锁 独占锁
- 多个进程获取有限资源操作模式
-
- 获取控制该资源的信号量
- 若信号量的值大于0,则进程可以使用该资源,为了表示该进程已获得该资源,需要将信号量的值减1
- 若信号等于0,则该进程休眠等待资源,直到信号量的值大于0,进程被唤醒,执行1步骤
- 当进程不再使用该资源时,为了表示进程释放该资源,需要将信号量的值加1,正在休眠等待该资源的其它进程将会被唤醒
- 信号量 类似于 锁
#include <sys/sem.h>
//semget 创建/获取信号量集 信号量数组
int semget(key_t key,int nsems,int semflg);
/*
该函数是以key作为键值创建一个信号量集合(nsems参数表示集合中信号量的数量),如果是获取已经存在的信号量集合则nsems可以取0
semflg取值:
0 - 获取,不存在则失败
IPC_CREAT - 创建,不存在则创建,存在即获取,除非IPC_EXCL
IPC_EXCL - 排斥,和IPC_CREAT一起使用,如果信号量集合存在则失败
成功返回信号量集合标识,失败返回-1
*/
//semop 操作信号量/信号量集合
int semop(int semid,struct sembuf *sops,unsigned nsops);
/*
semid参数是信号量集合的标识,semget函数的返回值
sops: 其实是一个数组的首地址 如果只有一个元素时,可以是一个元素的首地址
nsops:数组长度
sops数组中每个元素都是stuct sembuf的数据 执行操作如下:
若sem_op大于0,则将其加到sem_num下标所表示的信号量的计数值上,以表示对资源的释放
若sem_op小于0,则将其从sem_num下标所表示的信号量减去sem_op的绝对值,以表示对资源的获取
若sem_num信号量的计数值不够减(信号量数值不能为负),则此函数会阻塞,直到该信号量够减为止,以表示对资源的等待;
若sem_flg包含IPC_NOWAIT,则当sem_num信号量计数值不够减时,此函数不会阻塞,而是返回-1,errno设置为EAGAIN,以便在等待资源的同时还可以做其它处理
若sem_op等于0,则直到sem_num所表示的信号量的计数值为0时才返回,除非sem_flg包含IPC_NOWAIT
成功返回0,失败返回-1
*/
struct sembuf{
unsigned short sem_num; //信号量下标 下标从0开始,表示操作哪一个信号量
short sem_op; //操作数 1 -1
short sem_flg; //操作标记
};
//semctl 销毁/控制信号量集
int semctl(int semid,int semnum,int cmd);
int semctl(int semid,int semnum,int cmd,union semun arg);
/*
IPC_STAT- 获取信号量集合的属性,通过arg.buf输出
IPC_SET - 设置信号量集合的属性,通过arg.buf输入
sem_perm.uid
sem_perm.gid
sem_perm.mode
IPC_RMID- 立即删除信号量集合
此时所有阻塞在对该信号量集合的semop函数调用,都会立即返回失败,errno设置为EIDRM
GETALL - 获取信号量集合中每个信号量的计数值,通过arg.array输出
SETALL - 设置信号量集合中每个信号量的计数值,通过arg.array输入
GETVAL - 获取信号量集合中,下标为semnum信号量的计数值,通过返回值输出
SETVAL - 设置信号量集合中,下标为semnum信号量的计数值,通过arg.val输入
注意:只有针对信号量集合中具体某个信号量操作时,才会使用semnum参数,针对整个信号量集合操作,会忽略semnum
成功因cmd而异,失败返回-1
*/
union emun{
int val; //value for SETVAL
struct sem_ds *buf; //Buffer for IPC_STAT IPC_SE