系统编程 day12 (linux ) 消息队列 的函数 与知识

1.消息队列是啥?

消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。


2.消息队列的特点:

1.发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待(异步)。

2.新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。

3.消息队列随内核和进程相关,只有在内核重启或者显式删除一个消息队列时,该消息队列才会真正被删除。


3.消息队列的使用步骤:(函数的使用)

(1)msgget:得到一个消息队列,当这个消息队列存在的时候, 这个消息调用负责返回这个队列的标识号;如果这个队列不存在,就创建一个消息队列,然后返回这个消息队列的标识号 (2)msgsnd:向一个消息队列发送一个消息

(3)msgrcv:从一个消息队列中收到一个消息

(4)msgctl:在消息队列上执行指定的操作。根据参数的不同和权限的不同,可以执行检索、删除等的操作


4.函数的原型  参数  功能  返回值 

msgget--得到一个消息队列

头文件:#include<sys/types.h>

#include<sys/msg.h>

#include<sys/ipc.h>

函数原型:int msgget (key_t key, int msgflg);

参数:key 为由 ftok 创建的 key 值,msgflg 的低位用来确定消息队列的访问权限,如 0770。还可以附加以下参数值: IPC_CREAT 00001000//如果 key不存在,创建 IPC_EXCL 00002000//如果 key 存在,返回失败 IPC_NOWAIT 00004000 //如果需要等待,直接返回错误

返回值:成功返回IPC标识符,不成功返回-1


5.msgsnd()--发送信息到消息队列

头文件:sys/msg.h

原型: int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:msqid 为指定的消息队列标识符 msgp 为指向的用户定义缓冲区,

其结构如下:

struct msgbuf {   

 long mtype; //消息类型   

 char mtext[512]; //消息内容,使用时自己重新定义此结构

                        };

msgsz为发送信息的大小,其大小为 0到系统对消息队列的限制值。

msgflg用来指定在达到系统为消息队列所定的界限时应采取的操作。 可为以下值:  IPC_NOWAIT:若消息队列已满(或者是队列中的消息总数等于系统限制值,或队列中的字节总数等于系统限制值),则指定IPC_NOWAIT使得msgsnd立即出错返回EAGAIN。如果没有指定IPC_NOWAIT ,则进程阻塞直到有空间可以容纳要发送的消息,或从系统中删除了此队列在成功调用后,将对消息队列 msqid 数据结构的成员执行下列操作:     msg_qnum 以 1 为增量递增。     msg_lspid 设置为调用进程的进程 ID。     msg_stime 设置为当前时间。

返回值:成功返回0,失败返回-1


5.msgrcv--接收消息队列

头文件:sys/msg.h

原型:int msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long int msgtyp,int msgflg);

参数:msqid:消息队列描述符。  

 msgp:读取的消息存储到msgp指向的消息结构中。  

 msgsz:消息缓冲区的大小。  

 msgtyp:为请求读取的消息类型。  

 msgflg:操作标志位。

msgflg可以为IPC_NOWAIT,IPC_EXCEPT,IPC_NOERROR: IPC_NOWAIT:如果没有满足条件的消息,调用立即返回 IPC_EXCEPT:与msgtyp配合使用,返回队列中第一个类型不为msgtyp的消息; IPC_NOERROR:如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将被丢弃。

返回值:成功会返回消息的实际字节数,否则返回-1


6.msgctl--消息队列属性控制

头文件: #include<sys/types.h>

#include<sys/msg.h>

#include<sys/ipc.h>

原型:int msgctl (int msqid, int cmd, struct msqid_ds *buf)

参数:

msqid 为消息队列标识符,

cmd 为执行的控制命令,可为:     IPC_STAT:读取消息队列属性。     IPC_SET :设置消息队列属性。     IPC_RMID:删除消息队列。     IPC_INFO:读取消息队列基本情况 buf为msqid_ds 结构体类型的变量。用于存储读取的消息队列属性或者需要修改的消息队列属性

返回值:成功返回0,不成功返回-1


代码: (代码 有bug    那个 无用的字符数组 不要删   没有它,不能执行 )

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:消息队列
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/msg.h>

//ipcs  -q 查看命令

//1.消息队列功能的使用测试
//2.创建一个消息队列
//2.向消息队列中写入数据
//3.从消息队列中读取数据
//销毁消息队列
struct msgbuf
{
	long msgtype;  //8个字节
	char msgtext[512]; //字符串内容
};

int main()
{
	//获取一个键值
	key_t key = ftok(".",50);
	if(key < 0)
	{
		perror("ftok error\n");
		return -1;
	}
	printf("ftok is ok\n");
	printf("key is : %d\n",key);
	
	//获取一个消息队列
	int msgid = msgget(key,IPC_CREAT | 0666);
	if(msgid < 0)
	{
		perror("msgget is error\n");
		return -1;
	}
	printf("msgid is : %d\n",msgid);
	
	//向消息队列中添数据
	struct msgbuf msgstr = {1,"hello linux"};
	char *str = "hello linux";
	int msgerr = msgsnd(msgid,&msgstr,sizeof(msgstr),IPC_NOWAIT);
	if(msgerr <0)
	{
		perror("msgsnd error\n");
		return -1;
	}
	
	struct msgbuf msgstr1 = {0};
	char buff[128] = "";
	int msglen = msgrcv(msgid,&msgstr1,sizeof(msgstr1),1,0);
	printf("msgbuf is :%s msgtype is : %ld %d\n",msgstr1.msgtext,msgstr1.msgtype,msglen);
	
	//删除消息队列
	msgctl(msgid,IPC_RMID,NULL);

	return 0 ;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值