15_1msgctl的使用

#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;
}


运行结果:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章