#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
//IPC對象;消息隊列是linux內核給你持久化(我們可以從linux內核中獲取消息隊列的信息,修改消息隊列)
/*
The msqid_ds data structure is defined in <sys/msg.h> as follows:
//設置或返回消息隊列的信息,存在於用戶空間
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)
};
The ipc_perm structure is defined as follows (the highlighted fields are settable using
IPC_SET):
struct ipc_perm {
key_t __key; // Key supplied to msgget(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
};
*/
//通過msqid刪除消息隊列 ipcrm -q msqid
/*
//可發送的最長消息字節數
hzmct@U-64:~$ cat /proc/sys/kernel/msgmax
8192
//一個特定隊列的最大字節數(這個隊列中所有的消息長度之和)
hzmct@U-64:~$ cat /proc/sys/kernel/msgmnb
16384
//系統中的最大消息數
hzmct@U-64:~$ cat /proc/sys/kernel/msgmni
32000
*/
void showq(void * buf)
{
if(buf == NULL)
{
printf("buf == NULL ");
return;
}
struct msqid_ds *msqid_ds = (struct msqid_ds *)buf;
printf("************************show ipc msgq************************\n");
printf("該消息隊列對應的鍵:%x\n", msqid_ds->msg_perm.__key);
printf("該消息隊列訪問權限:%o\n", msqid_ds->msg_perm.mode);
printf("該消息隊列的序號:%d\n", msqid_ds->msg_perm.__seq);
printf("該消息隊列 UID of owner:%d\n", msqid_ds->msg_perm.uid);
printf("該消息隊列 GID of owner:%d\n", msqid_ds->msg_perm.gid);
printf("該消息隊列 UID of creator:%d\n", msqid_ds->msg_perm.cuid);
printf("該消息隊列 GID of creator:%d\n", msqid_ds->msg_perm.cgid);
printf("消息隊列中的消息個數:%d\n", (int)msqid_ds->msg_qnum);
printf("當前消息隊列中有多少字節:%ld\n", (long int)msqid_ds->__msg_cbytes);
printf("該消息最後發送的時間:%ld, 進程id:%d\n", (long int)msqid_ds->msg_stime, msqid_ds->msg_lspid);
printf("該消息最後接收的時間:%ld, 進程id:%d\n", (long int)msqid_ds->msg_rtime, msqid_ds->msg_lrpid);
printf("接收該消息的修改時間:%ld\n", (long int)msqid_ds->msg_ctime);
printf("消息隊列所有消息之和最大字節數(取決於系統):%d\n", (int)msqid_ds->msg_qbytes);
}
//IPC_STAT 獲取消息隊列信息
#if 0
int test()
{
int msgid;
int ret;
msgid = msgget(0x1234, 0666|IPC_CREAT);
if (msgid == -1)
{
if (errno == ENOENT)
{
printf("自己檢查錯誤, 消息隊列不存在\n");
}
perror("msgget");
return -1;
}
printf("msgid:%d\n", msgid);
printf("創建消息隊列成功\n");
struct msqid_ds buf;
memset(&buf, 0, sizeof(struct msqid_ds));
//獲取隊列狀態
ret = msgctl(msgid, IPC_STAT, &buf);
if (ret == -1)
{
perror("mdgctl");
}
showq(&buf);
return 0;
}
#endif
//IPC_SET 設置消息隊列信息(先獲取在設置)
#if 1
int test()
{
int msgid;
int ret;
msgid = msgget(0x1234, 0666|IPC_CREAT);
if (msgid == -1)
{
if (errno == ENOENT)
{
printf("自己檢查錯誤, 消息隊列不存在\n");
}
if (errno == EACCES)
{
printf("自己檢查錯誤, 用戶進程沒有權限訪問\n");
}
perror("msgget");
return -1;
}
printf("msgid:%d\n", msgid);
printf("創建消息隊列成功\n");
struct msqid_ds buf;
memset(&buf, 0, sizeof(struct msqid_ds));
//獲取隊列狀態
ret = msgctl(msgid, IPC_STAT, &buf);
if (ret == -1)
{
perror("獲取消息隊列狀態");
}
//修改消息隊列的訪問模式權限
buf.msg_perm.mode = 0444;
ret = msgctl(msgid, IPC_SET, &buf);
if (ret == -1)
{
perror("修改消息隊列");
}
showq(&buf);
//刪除消息隊列
ret = msgctl(msgid, IPC_RMID, &buf);
if (ret == -1)
{
perror("刪除消息隊列");
}
return 0;
}
#endif
int main()
{
test();
return 0;
}
運行結果: