找回密码
 注册
搜索
热搜: 回贴
微赢网络技术论坛 门户 服务器 Linux/BSD 查看内容

消息队列(报文队列)实践到内核

2009-12-20 13:21| 发布者: admin| 查看: 32| 评论: 0|原作者: 小可爱

我是无名小卒,一直想写一些关于内核方面的资料,学习内核很久了,市面上的内核书我都读过了,无法对任何一本书加以总结,因为他就象linux的内核一样在不断更新和升级,针对2.6内核现在市面上非常缺少相关内核的分析资料情况,当然,也有不少网友写了一些关于2.6内核的博客文章,我也看过,但是写的不够深刻具体,总是在内核的过程上粗略的一笔带过,因此我下决心只要有空闲时间就写一些日志来与大家分享,很多书籍和博客都是直接剖析内核的,我读过这些书后发现,这种学习方法虽然快,但是效果不太好,特别是我读了几遍后还是对很多知识点和结构记忆不深,对初学者来说更是枯燥无味的过程,使很多朋友放弃了研读内核代码的兴趣,确实如此,就象缺一张好的导游地图一样,如果我们目的明确,但是缺乏了指路的地图那无非是在大森林里迷了路一样,再高的旅游兴趣也荡然无存,因此,我想要是有一本书或者资料能够在实践中逐步深入到内核该有多好,那样能够使我们在即看到效果的时候导游到如何产生这样效果的内核中将会是一件非常有趣的事情,肯定能够轻松地掌握全部想要的知识,目前市面上有这样的书,但是评价不怎么好,所以我想根据多年读内核的书来整理和书写这类的文章,希望对有兴趣的朋友起到导游地图的效果。这些文章有可能是来自大家所熟悉的资料中也有可能来自互联网,总之,多多益善,我不会在文中注明具体出处,也希望原作者勿怪,我们的目标是大家共同进步。

这节我们开始消息队列(也有称报文队列)的实践到内核,我是无名小卒,很多书上讲到的消息队列都很枯燥,我尽量写的易读易懂,避免书者之风,我们的目标是深入到内核的细节中去,从实践的应用上追踪到内核的实现。

消息队列的概念相信大家能从字面上看的出,他的优点资料非常全面,不介绍了我们直接进入主题,看代码
我们在实验中写二个程序一个是msg1.c是接受消息队列程序,另一个是msg2.c是发送消息队列用的,在这二个程序中可以创建新的消息队列,但是在接受的程序中在完成接受后我们删除消息队列。
下面是msg1.c接受消息队列的程序代码:

#include unistd.h>
#include stdio.h>
#include stdlib.h>
#include string.h>
#include sys/types.h>
#include sys/ipc.h>
#include sys/msg.h>
struct my_msg_st{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running=1;
int msgid;
struct my_msg_st some_data;
long int msg_to_receive=0;
下面我们要建立一个消息队列,这个函数就是msgget()
msgid=msgget((key_t)1234,0666|IPC_CREAT);
if(msgid==-1){
fprintf(stderr,"msgget failed\n");
exit(EXIT_FAILURE);
}
while(running){
if(msgrcv(msgid,(void*)&some_data,BUFSIZ,msg_to_receive,0)==-1){
fprintf(stderr,"msgrcv failed\n");
exit(EXIT_FAILURE);
}
上面的while循环中是通过msgrcv()函数从消息队列中接受消息直到没有消息为止,我们继续往下看
printf("you wrote: %s\n",some_data.some_text);
if(strncmp(some_data.some_text,"end",3)==0){
running=0;
}
}
if(msgctl(msgid,IPC_RMID,0)==-1){
fprintf(stderr,"msgctl failed \n");
exit(EXIT_FAILURE);
}
上面是通过msgctl()函数删除消息队列
exit(EXIT_SUCCESS);
}

第二个是发送消息队列的程序代码,这个代码相对于上面是小了许多,在下面的程序main()中,删除了msg_to_receive,并且用buffer[BUFSIZ]替换了。下面的程序代码将发送文字给接受消息队列程序,具体的msg2.c的代码如下:
#include unistd.h>
#include stdio.h>
#include stdlib.h>
#include string.h>
#include sys/types.h>
#include sys/ipc.h>
#include sys/msg.h>
struct my_msg_st{
long int my_msg_type;
char some_text[BUFSIZ];
};
int main()
{
int running=1;
int msgid;
struct my_msg_st some_data;
char buffer[BUFSIZ];
上面就是我们删除了msg_to_receive,并且用buffer[BUFSIZ]替换了
msgid=msgget((key_t)1234,0666|IPC_CREAT);
尽管上面也用了msgget()函数但是这个函数有查询功能就是有相同名称的消息队列就不自创建,深入内核时会看到这个作用。
if(msgid==-1){
fprintf(stderr,"msgget failed\n");
exit(EXIT_FAILURE);
}
while(running){
printf("enter some text:");
fgets(buffer,BUFSIZ,stdin);
some_data.my_msg_type=1;
strcpy(some_data.some_text,buffer);
上面是我们在控制台上让用户输入一些文字并复制声明的结构变量some_data的some_text,它是一个char 类型的数组,我们继续往下看
if(msgsnd(msgid,(void*)&some_data,BUFSIZ,0)==-1){
fprintf(stderr,"msgsnd failed \n");
exit(EXIT_FAILURE);
}
我们通过msgsnd()函数将some_data做为消息发送出给接收消息队列的程序
if(strncmp(some_data.some_text,"end",3)==0){
running=0;
}
}
exit(EXIT_SUCCESS);
}
至于上面其余的代码相信有C语言基础的朋友都能看懂,如果你还是看不明白,需要补习一下C语言的基础了,下面编译程序
$gcc -o msg2 msg2.c
$gcc -o msg1 msg1.c
启动发送消息队列程序并输入下面的文字
$./msg2 
Enter some text:hello
Enter some text:Are you ready?
Enter some text:end
启动接收消息队列程序自动显示出文字
$./msg1
You wrote:hello
You wrote:Are you ready?
You wrote:end
$
由于时间关系今天暂且完成实验部分,明天继续完成深入内核





最新评论

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-30 01:41 , Processed in 0.165924 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部