IPC 消息队列 msg

消息队列相关的系统参数:

(1)

# ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 7744

max locked memory       (kbytes, -l) 32

max memory size         (kbytes, -m) unlimited

open files                      (-n) 65535

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200   <--- The maximum number of bytes in POSIX message queues 这个选项仅对 POSIX 消息队列有影响。

real-time priority              (-r) 0

stack size              (kbytes, -s) 8192

cpu time               (seconds, -t) unlimited

max user processes              (-u) 7744

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

(2)

kernel.msgmnb = 65536   //队列中 所有消息 最大字节总数

kernel.msgmni = 16      //系统管理的最多的 消息队列数

kernel.msgmax = 65536   //消息队列可以发送的 单个消息 的最大字节数

【重要】:

多进程读写消息队列不需要考虑进程同步,内部有同步保护, 这点是比共享内存要方便的地方。

测试:

struct MY_MSG

{

long type;

char msg[1024];  

};

该结构MY_MSG尺寸为 4+1024=1028字节

启动两个进程msg_snd.bin,执行 msgsnd(msgid, (struct msgbuf*)&oMY_MSG, sizeof(MY_MSG), 0);

通过ipcs可以看到该消息队列中有2个消息,总大小为 2056字节

# ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666        2056         2

即使关闭进程msg_snd.bin,消息队列中的数据会一直保存,除非有其他进程主动接收或者重启系统。

启动进程msg_rcv.bin,执行 msgrcv(msgid, (struct msgbuf*)&rcv, sizeof(MY_MSG), 100, 0);

# ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666        1028         1

消息队列中的1个消息被读取。

异常测试1:msgsnd 发送的消息尺寸和实际大小不符

启动进程msg_snd.bin, 执行msgsnd(msgid, (struct msgbuf*)&oMY_MSG, sizeof(long), 0);

# ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666                   1  

启动进程msg_rcv.bin,执行 msgrcv(msgid, (struct msgbuf*)&rcv, sizeof(MY_MSG), 100, 0);

# ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666        0            0

获取该消息,但是该消息只有4字节,MY_MSG.msg没有内容

异常测试2:msgsnd 发送的消息尺寸和实际大小不符

启动进程msg_snd.bin, 执行msgsnd(msgid, (struct msgbuf*)&oMY_MSG, sizeof(MY_MSG), 0);

# ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666         1028           1  

启动进程msg_rcv.bin,执行 msgrcv(msgid, (struct msgbuf*)&rcv, sizeof(long), 100, 0);

执行失败, 报错如下:

rcv msg failed. nRet: =-1

msgrcv failed. errno:7, errmsg:Argument list too long

再启动进程msg_snd.bin, 执行msgsnd(msgid, (struct msgbuf*)&oMY_MSG, sizeof(long), 0);

ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666         1032         2

再次启动进程msg_rcv.bin,执行 msgrcv(msgid, (struct msgbuf*)&rcv, sizeof(long), 100, 0);

执行依然失败, 报错如下:

rcv msg failed. nRet: =-1

msgrcv failed. errno:7, errmsg:Argument list too long

【总结】:

(1)消息队列中的消息是FIFO的模式, msgrcv总是获取最前面的消息。

(2)msgrcv 获取的消息尺寸一定要大于等于消息队列中的消息尺寸,否则会报错 "msgrcv failed. errno:7, errmsg:Argument list too long",

   除非 msgrcv flag设置MSG_NOERROR选项, 获取部分数据, 并且将该消息移除消息队列。 msgrcv(msgid, (struct msgbuf*)&rcv, 4, 100, MSG_NOERROR );

异常测试3:修改系统参数,创建消息队列失败

# sysctl -a |grep msg

kernel.msgmnb = 65536

kernel.msgmni = 16     //消息队列个数

kernel.msgmax = 65536

# ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666        0            0          

0x11223344 32769      root       666        0            0          

0x11223366 65538      root       666        4            1

# sysctl -w kernel.msgmni=2   <---- 修改消息队列

# ipcs -q     <---- 原来已经建立好的消息队列保持不变

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223355 0          root       666        0            0          

0x11223344 32769      root       666        0            0          

0x11223366 65538      root       666        4            1

./msg_snd.bin   <----- 新建消息队列报错

create ipc msg failed. msgid-1

msgget failed. errno:28, errmsg:No space left on device

测试4:在多线程环境下使用消息队列

单进程启动2个线程组。

一个线程组只有1个线程, 负责向消息队列中插入100个消息

#ipcs -q

------ Message Queues --------

key        msqid      owner      perms      used-bytes   messages    

0x11223388 32768      root       666        1490         100

另一个线程组包含5个线程,负责从消息队列中读取消息,通过测试发现多线程获取是互斥的。

每个线程各20个消息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值