linux msgctl函数,linux网络编程之System V 消息队列(一):消息队列内核结构和msgget、msgctl 函数...

一、消息队列 1、消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 2、每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值 3、消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列的读

一、消息队列

1、消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法

2、每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值

3、消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先入先出。

4、消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI),,这三个参数都可以查看:

simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ cat /proc/sys/kernel/msgmax

8192

simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ cat /proc/sys/kernel/msgmnb

16384

simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ cat /proc/sys/kernel/msgmni

1711

二、IPC对象数据结构

内核为每个IPC对象维护一个数据结构

struct ipc_perm {

key_t          __key;       /* Key supplied to xxxget(2) */

uid_t          uid;         /* Effective UID of owner */

gid_t          gid;         /* Effective GID of owner */

uid_t          cuid;        /* Effective UID of creator */

gid_t          cgid;        /* Effective GID of creator */

unsigned short mode;        /* Permissions */

unsigned short __seq;       /* Sequence number */

};

消息队列,共享内存和信号量都有这样一个共同的数据结构。

三、消息队列结构

struct msqid_ds {

struct ipc_perm msg_perm;     /* Ownership and permissions */

time_t    msg_stime;    /* Time of last msgsnd(2) */

time_t    msg_rtime;    /* Time of last msgrcv(2) */

time_t    msg_ctime;    /* Time of last change */

unsigned long    __msg_cbytes; /* Current number of bytes in

queue (nonstandard) */

msgqnum_t    msg_qnum;     /* Current number of messages

in queue */

msglen_t    msg_qbytes;   /* Maximum number of bytes

allowed in queue */

pid_t                 msg_lspid;      /* PID of last msgsnd(2) */

pid_t                  msg_lrpid;      /* PID of last msgrcv(2) */

};

可以看到第一个条目就是IPC结构体,即是共有的,后面的都是消息队列所私有的成员。

四、消息队列在内核中的表示

aa95b08398d3e0fdc432e8758ba44cdf.gif

消息队列是用链表实现的,这里需要提出的是MSGMAX指的是一条消息的纯数据大小的上限,上图是一个消息队列,则其纯数据总和不能超过MSGMNB,像这样一条消息队列,系统含有的总数不能超过MSGMNI 个。

五、msgget 和 msgctl 函数

#include

#include

#include

(1)int msgget(key_t key, int msgflg);

功能:用来创建和访问一个消息队列

参数

key: 某个消息队列的名字

msgflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的

返回值:成功返回一个非负整数,即该消息队列的标识码;失败返回-1

创建流程如下图所示:

2e73170e7d52bc5dc112a126918a6024.gif

注意,IPC_PRIVATE 不是一个msgflg 而是一个key_t 类型,如果指定key = IPC_PRIVATE,则无论某个 key_value 这个消息队列是否存在,都会再创建一个key_value 消息队列,但他们的标识码msqid是不一样的,且指定IPC_PRIVATE 产生的是私有的消息队列。

写个小程序测试一下这个函数:/*************************************************************************

> File Name: basic.c

> Author: Simba

> Mail: dameng34@163.com

> Created Time: Tue 12 Mar 2013 06:54:20 PM CST

************************************************************************/

#include

#include

#include

#include

#include

#include

#include

#define ERR_EXIT(m)

do {

perror(m);

exit(EXIT_FAILURE);

} while(0)

int main(void)

{

int msgid;

msgid = msgget(1234, 0666 | IPC_CREAT);

if (msgid == -1)

ERR_EXIT("msgget");

printf("msgget successn");

msgid = msgget(1234, 0);

printf("msgid=%dn", msgid);

return 0;

}

程序先创建一个消息队列,名字为1234,接着打开这个消息队列,当flags = 0 表示按原来权限打开。

输出如下:

simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ ./msgget

msgget success

msgid=0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值