|
消息队列的属性保存在系统维护的数据结构 msqid_ds 中,用户可以通过函数 msgctl 获取或设置消息队列属性。msgctl 定义在头文件 sys/msg.h 中,原型如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgctl 系统调用对 msgqid 标识的消息队列执行 cmd 操作,系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID ,意义分别如下:
IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。 IPC_SET : 该命令用来设置消息队列的属性,要设置的属性存储在 buf 中,可设置的属性包括: msg_perm.uid , msg_perm.gid , msg_perm.mode 以及 msg_qbytes . IPC_RMID : 从内核中删除 msqid 标识的消息队列。
测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define BUF_SIZE 256
#define PROJ_ID 32
#define PATH_NAME "."
void getmsgattr (int msgid, struct msqid_ds msq_info);
int main()
{
/*用户自定义缓冲区*/
struct mymsgbuf {
long msgtype;
char ctrlstring[BUF_SIZE];
} msgbuffer;
int qid; /*消息队列标识符*/
int msglen;
key_t msgkey;
struct msqid_ds msg_attr;
/*获取键值*/
if ((msgkey = ftok (PATH_NAME, PROJ_ID)) == -1) {
perror ("ftok error!\n");
exit (1);
}
/*获取消息队列标识符*/
if ((qid = msgget (msgkey, IPC_CREAT|0660)) == -1) {
perror ("ftok error!\n");
exit (1);
}
getmsgattr (qid, msg_attr); /*输出消息队列的属性*/
/*发送一条消息到消息队列*/
msgbuffer.msgtype = 3;
strcpy (msgbuffer.ctrlstring, "Another message");
msglen = sizeof (struct mymsgbuf) - 4;
if (msgsnd (qid, &msgbuffer, msglen, 0) == -1) {
perror ("msgsnd error!\n");
exit (1);
}
getmsgattr (qid, msg_attr); /*再输出消息队列的属性*/
/*设置消息队列属性*/
// msg_attr.msg_perm.uid = 1001;
// msg_attr.msg_perm.gid = 100;
// if (msgctl (qid, IPC_SET, &msg_attr) == -1) {
// perror ("msg set error!\n");
// exit (1);
// }
/*修改后再观察其属性*/
// getmsgattr (qid, msg_attr);
if (msgctl (qid, IPC_RMID, &msg_attr) == -1) {
perror ("delete msg error!\n");
exit (1);
} else {
system ("ipcs");
exit (0);
}
//getmsgattr (qid, msg_attr);
exit (0);
}
void getmsgattr (int msgid, struct msqid_ds msg_info)
{
if (msgctl (msgid, IPC_STAT, &msg_info) == -1) {
perror ("msgctl error!\n");
return ;
}
printf ("*****information fo message queue*****\n");
printf ("last msgsnd to msq time is %s\n", ctime (&(msg_info.msg_stime)));
printf ("last msgrcv time from msg is %s\n", ctime (&(msg_info.msg_rtime)));
printf ("last change msq ime is %s\n", ctime (&(msg_info.msg_rtime)));
printf ("perm-uid is %d\n", msg_info.msg_perm.uid);
printf ("perm-gid is %d\n", msg_info.msg_perm.gid);
printf ("current number of bytes on queue is %d\n", msg_info.msg_cbytes);
printf ("number of messages in queue is %d\n", msg_info.msg_qnum);
printf ("max number of bytes on queue is %d\n", msg_info.msg_qbytes);
printf ("pid of last msgsnd is %d\n", msg_info.msg_lspid);
printf ("pid of last msgrcv is %d\n", msg_info.msg_lrpid);
printf ("******information end!**********\n");
} 运行及输出:beyes@linux-beyes:~/C/queue> ./opmsg.exe
*****information fo message queue*****
last msgsnd to msq time is Thu Jan 1 08:00:00 1970
last msgrcv time from msg is Thu Jan 1 08:00:00 1970
last change msq ime is Thu Jan 1 08:00:00 1970
perm-uid is 1000
perm-gid is 100
current number of bytes on queue is 0
number of messages in queue is 0
max number of bytes on queue is 65536
pid of last msgsnd is 0
pid of last msgrcv is 0
******information end!**********
*****information fo message queue*****
last msgsnd to msq time is Fri Sep 4 01:15:24 2009
last msgrcv time from msg is Thu Jan 1 08:00:00 1970
last change msq ime is Thu Jan 1 08:00:00 1970
perm-uid is 1000
perm-gid is 100
current number of bytes on queue is 256
number of messages in queue is 1
max number of bytes on queue is 65536
pid of last msgsnd is 13190
pid of last msgrcv is 0
msg uid is 1000
msg gid is 100
******information end!**********
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 327681 beyes 600 393216 2 dest
0x00000000 360450 beyes 600 393216 2 dest
0x00000000 393219 beyes 600 393216 2 dest
0x00000000 425988 beyes 600 393216 2 dest
0x00000000 458759 beyes 600 393216 2 dest
0x00000000 491528 beyes 600 393216 2 dest
0x00000000 524297 beyes 600 393216 2 dest
0x00000000 557066 beyes 600 393216 2 dest
0x00000000 589835 beyes 600 393216 2 dest
0x00000000 622604 beyes 600 393216 2 dest
0x00000000 655373 beyes 600 393216 2 dest
0x00000000 1605646 beyes 600 393216 2 dest
0x00000000 720911 beyes 600 393216 2 dest
0x00000000 2457616 beyes 600 5752320 2 dest
0x00000000 819217 beyes 600 393216 2 dest
0x00000000 851986 beyes 600 393216 2 dest
0x00000000 2621459 beyes 600 393216 2 dest
------ Semaphore Arrays --------
key semid owner perms nsems
0x4d08b330 196612 beyes 600 8
------ Message Queues --------
key msqid owner perms used-bytes messages
说明:
由于程序是在普通用户权限下运行,所以无法创建消息的权限,故在程序中对设置权限(IPC_SET) 部分屏蔽掉。
在程序最后,调用了 IPC_RMID 命令,此命令删除掉消息队列中所有的消息,删除的结果是不存在这个消息队列,这从最后 ipcs 命令中也可以看出。如果在删除消息队列后,仍然调用 msgctl ,就会出现参数非法提示错误! |
|