五、消息队列
消息队列就是一个消息的链表。可以把消息看作是一个记录,具有特定格式。进程可以向中按照一定的规则添加新消息;另一些进程则可以从消息队列中读走消息。目前有POSIX消息队列,但系统V消息队列被大量使用。
1、持续性
系统V消息队列是随内核持续的,只有在内核重启或人工删除时,该消息队列才会被删除。
2、键值
消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的描述字,必须提供该消息队列的键值。
键值的获得:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(char *pathname,char proj)
功能:返回文件名对应的键值。
pathname:文件名
proj:项目名(不为0即可)
3、打开和创建消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key,int msgflg)
key:键值,由ftok获得
msgflg:标志位。
返回值:与键值key相对应的消息队列描述字。
标志位msgflg的值:
IPC_CREAT:创建新的消息队列
IPC_EXCL:与IPC_CREAT一同使用,表示如果要创建的消息队列已经存在,则返回错误。
IPC_NOWAIT:读写消息队列要求无法得到满足时,不阻塞。
在以下两种情况下,将创建新的消息队列:
1)如果没有与键值key相对应的消息队列,并且msgflg中包含了IPC_CREAT标志位
2)key参数为IPC_PRIVATE。
4、发送消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msgid,struct msgbuf *msgp,int msgsz,int msgflg)
功能:向消息队列中发送一条消息,成功时返回0,失败时返回-1。
参数:
msgid:已打开的消息队列的ID
msgp:指向消息缓冲区得指针,此位置用来暂时存储发送和接收的消息,是一个用户可自定义的通用结构,
msgsz:消息数据的长度
msgflg:发送消息标志,有意义的msgflg标志位IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息,msgsnd是否等待。
5、消息格式
struct msgbuf
{
long mtype;/*消息类型>0*/
char mtext[1];/*消息数据的首地址*/
}
6、接收消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msgid,struct msgbuf *msgp,int msgsz,long msgtyp,int msgflg)
功能:从msgid代表的消息队列中读取一个msgtyp类型的消息,并把消息存储在msgp指向的msgbuf结构中。在成功的读取了一条消息后,队列中的这条消息将被删除。
六、信号量
信号量(又名:信号灯)与其他进程间通讯方式不大一样,主要用途是保护临界资源。进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可用于进程同步。
1、分类
二值信号灯:信号灯的值只能取0或1,类似于互斥锁。但两者有不同:信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁。
计数信号灯:信号灯的值可以取任意非负数。比如一个信号灯的值是10,那么每一个进程访问资源,信号灯就减1,直到减为0时其他进程就无法访问了,换句话说,信号灯的值就是有多少个进程可以访问的个数。
2、创建或打开
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key,int nsems,int semflg)
key:键值,有ftok获得
nsems:指定打开或者创建的信号灯集中将包含信号灯的数目
semflg:标识,同消息队列一样
返回值:信号量集得ID
3、操作
int semop(int semid.struct sembuf *sops,unsgined nsops)
功能:对信号量进行控制(对信号量进行获取还是释放)
semid:信号量集得ID
sops:是一个操作数组,表明要进行什么操作
nsops:sops所指向的数组的元素个数
struct sembuf
{
unsigned short sem_num;
short sem_op;
short sem_flg;
}
sem_num:要操作的信号量在信号集中的编号,第一个信号编号是0
sem_op:如果是正值,该值会加到现有的信号量值中,通常用于释放信号量;如果为负值,而其绝对值又大于信号的现值,操作将会阻塞,知道信号值大于等于sem_op的绝对值,通常用于获取信号量;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0.
sem_flg:信号操作标志,可能有两种值:
IPC_NOWAIT:对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
IPC_UNDO:程序结束时(不论正常还是不正常)释放信号量,这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。
四、进程间通信二
最新推荐文章于 2023-07-19 01:06:30 发布