Linux - 消息队列

消息队列是由内核维护的消息链表。每个消息链表有一个名字和标识id,名字在进程之间通用,标识id被内核使用,名字也称为key,被用户使用,一个消息队列有一个公共的key,这个公共的key是大家都知道的,但是为了避免冲突,可以使用

key_t ftok(const char *path, int id);

来获得一个key。第一个参数是文件路径,第二个参数是项目id。这样所有的进程都只引用同一个文件和相同的项目id就可以避免key的冲突。

int msgget(key_t key, int flags);

获得一个消息队列,这里的获得包括创建(根据flags指定的值确定)。msgget得到队列标识符,key指定队列公共key,key可以取IPC_PRIVATE, 用来标识这个key的值不重要,因为我是私自用的。

flags可取下面的值的或:

flag作用
IPC_CREAT当key对应的信号量不存在时创建它
IPC_EXCL当key对应的信号量已经存在时,返回出错
mode类似于0660的权限,如果不设置其它进程可能没有权限访问
int msgctl(int id, int cmd, struct msqid_ds *buf);

对id对应的消息队列进行cmd指定的操作,而有一部分操作需要buf。

cmd说明
IPC_STAT获取该队列的信息存到buf中
IPC_SET设置队列信息中的uid, gid, mode, qbytes为buf中的值
IPC_RMID删除队列,只要一删除,立即生效,其它正在对该队列的动作立即失败返回。
struct msqid_ds
{
    struct ipc_perm msg_perm;   //permission
    msgqnum_t       msg_qnum;   //消息的个数
    msglen_t        msg_qbytes; //同时在队列中的最大长度
    pid_t           msg_lspid;
    pid_t           msg_lrpid;
    time_t          msg_stime;
    time_t          msg_rtime;
    time_t          msg_ctime;
};
int msgsnd(int msgqit, const char *ptr, size_t nbytes, int flag);

发送一个消息,一个消息包括一个消息类型和数据,ptr指向一个长整形,长整形之后跟着数据,nbytes标至数据长度,flags可以被指定为IPC_NOWAIT.

ptr可能是这样的:

struct msg
{
  long mtype;
  char mtext[512];
};

这个时候,nbytes为512, 函数成功返回0, 失败返回-1.

flags IPC_NOWAiT.

ssize_t msgrcv(int id, void *ptr, size_t nbytes, long type, int flag);

ptr和snd相同,nbytes标识数据长度,type用来标志要接收的消息类型:

type说明
>0接收type类型的消息中最早的一个。
=0接收所有消息中的最早的一个。
< 0接收小于type绝对值中类型值最小的那个。

flag同样可取IPC_NOWAIT.


经过验证,id是内核中唯一的值,和文件描述符不同,内核中用的哪个消息队列标识符程序中就用哪个,所有的进程都用一个标识符,所以,只要知道内核所用标识符的id就不用msgget都可以了,但一般没法知道,只能通过提前指定或者通过ftok来转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值