消息队列、信号量以及共享内存被称作 XSI IPC,它们均来自system V的IPC功能,因此具有许多共性。

键和标识符:

  内核中的每一种IPC结构(比如信号量、消息队列、共享内存)都用一个非负整数的标识符加以标示(如共享内存的shmid、信号量的semid、以及消息队列的msgid)。不同于文件描述符,IPC标识符不是一个小的非负整数,它是一个int型的整数,当一个标识符被创建,以后又被删除时,这个整数持续加1,达到整型的最大值后,重新回到0。

  但是每一个IPC对象在内核中的标识符只能在内部被识别,为了让不同的进程能够在同一个IPC对象上汇合,还需要一个外部的标识来表示一个IPC 对象,这就是key 键值。或者可以这样理解:标识符是一个打开了的IPC对象的描述符,而键值则让进程获得这个标识符。

  当我们通过一个键值创建了一个IPC对象以后,就可以用这个IPC对象的标识符操作这个IPC对象。例如当进程用指定的键值获得一个共享内存的标识符shmid以后,就可以通过这个标识符将共享内存映射到自身的地址空间上,当然后续对共享内存的操作也是基于这个标识符。

消息队列编程:

  消息队列作为XSI IPC的一种,许多实现和操作和前面描述的信号量和共享内存有很多相似的地方。先简述一下消息队列的原理:消息队列的本质就是一个消息的链表,而每个消息的结构如下

struct msgbuf {

                    long mtype;       /* message type, must be > 0 */

              char mtext[1];    /* message data */

           };

mtype:消息的类型        mtext[]: 消息中的数据

也就是说消息队列就是一个数据域是以上结构体的链表。既然了解了一个消息队列的本质就是一个链表,可以想象,如果进程间要通过消息队列通信,那么发送消息的进程的主要工作就是要构建一个数据域,然后交给内核来插入到链表中,而接收消息的进程就是通过内核函数来将数据从消息队列中取出来。消息队列还有如下特点:

 *消息队列的消息类型可以不同,进程取出消息时可以指定消息类型取出需要的消息

 *当进程取出一条消息后,该消息会立即被移出消息队列

利用消息队列通信主要由以下操作完成:

 *创建/打开消息队列   :int msgget(key_t key, int msgflg);

 *发送消息                 :int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)

 *接收消息                 :ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)

 *删除消息队列           :int msgctl(int msqid, int cmd, struct msqid_ds *buf)

这些函数都可以通过man命令查到具体的用法,这里就不在详细解释,下面是一个测试的范例:

send 程序:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h> #define TEXT_SZ 2048
struct msgt
{
long msgtype;
char msgtext[TEXT_SZ];
}; int main()
{
int msgid;
key_t key;
int running = ;
struct msgt msg_data;
int msgtype;
key = ftok("/home/application/massage_queue",);
//创建消息队列
msgid = msgget(key, IPC_CREAT);
//循环
while(running)
{
printf("Please Input msgtype,Input 0 to quit!\n");
scanf("%d",&msgtype);
printf("Please Input datas!\n"); //从终端读取数据
scanf("%s",msg_data.msgtext);
//将数据写入消息队列
msg_data.msgtype = msgtype;
msgsnd(msgid, &msg_data, sizeof(msg_data), ); if(strncmp(msg_data.msgtext,"end",)==)
{
msgsnd(msgid, "end", , );
running = ;
}
}
//删除消息队列
msgctl(msgid, IPC_RMID, );
return ; }

receive 程序:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <unistd.h> #define TEXT_SZ 2048
struct msgt
{
long msgtype;
char msgtext[TEXT_SZ];
}; int msgid;
void childprocess()
{
struct msgt msg_d;
int running = ;
while(running)
{
//接受消息队列中的数据
msgrcv(msgid, &msg_d, sizeof(msg_d), ,);
//打印数据
printf("Receive datas from queue:%s",msg_d.msgtext);
if(strncmp(msg_d.msgtext,"end",)==)
{
running = ;
}
} }
int main()
{ key_t key;
pid_t pid;
int i;
key = ftok("/home/application/massage_queue",);
//打开消息队列
msgid = msgget(key, IPC_EXCL); for(i=;i<;i++)
{
pid = fork();
if(pid<)
{
printf("fork error!\n");
}
else if(pid==)
{
childprocess();
}
} return ;
}

当两个程序运行起来以后可以发现通过send成序发送的数据在receive 中可以接收到,说明这些函数的调用很成功,同时也证明了消息队列的通信是成功的。

Linux 消息队列编程的更多相关文章

  1. linux消息队列编程实例

    转自:linux 消息队列实例 前言: 消息队列就是一个消息的链表.可以把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程可以向其中按照一定的规则添加新消息:对消息队列有读权 ...

  2. linux消息队列应用编程

    消息队列:  消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法   每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值   消息队列也有管道一样的不足,就是每个消息的 ...

  3. LINUX消息队列实战之一

    前言 能说能抄能论皆不算,能写能打才是真功夫. 唠叨 反正我也是一个孤独的程序猿,多说一些奇奇怪怪的唠叨也无妨,第一次写消息队列,书本的东西和实战很不同,根据实战总结的一些注意事项会和大家分享,也敲打 ...

  4. linux 消息队列的限制

    消息队列的系统限制 作者:冯老师,华清远见嵌入式学院讲师. 消息队列是System V的IPC对象的一种,用于进程间通信,会受到系统的限制,本文主要描述了三个限制.第一:议个消息的最大长度:第二:消息 ...

  5. linux消息队列通信

    IPC机制 进程间通信机制(Inter Process Communication,IPC),这些IPC机制的存在使UNIX在进程通信领域手段相当丰富,也使得程序员在开发一个由多个进程协作的任务组成的 ...

  6. Linux消息队列应用

    #include"sys/types.h" #include "sys/msg.h" #include "unistd.h" #includ ...

  7. linux消息队列操作

    对消息队列的操作无非有以下三种类型: 1. 打开或创建消息队列消息队列的内核持续性要求每一个消息队列都在系统范围内相应唯一的键值,所以,要获得一个消息队列的描写叙述字,仅仅需提供该消息队列的键值就可以 ...

  8. linux消息队列的使用

    消息队列 *消息队列是内核地址空间中的内部链表,通过内核在各个进程之间传递的内容.消息顺序发送到消息队列中,每个消息队列都有IPC标识符唯一地进行标识. msgbuf结构 struct msgbuf{ ...

  9. Linux消息队列

    #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/ms ...

随机推荐

  1. 搜索算法:深度优先搜索(DFS)

    关于深搜的介绍,在网上有很多,不再赘述.主要以题目形式实例讲解. POJ - 1321 (http://poj.org/problem?id=1321) 题目大意:给出一个棋盘,棋子不能同行同列,求放 ...

  2. ios 中的半屏幕底部弹出框

    static UIView *modalView;if (modalView) { [modalView removeFromSuperview]; modalView = nil; return; ...

  3. kvm usb2.0

    Virt-Manager adds support for usb2 Wednesday, April 4, 2012 - 10:40 Haydn Solomon The most recent re ...

  4. xom报错 Exception in thread "main" java.net.UnknownHostException: file

    Exception in thread "main" java.net.UnknownHostException: file at java.net.AbstractPlainSo ...

  5. ar技术序章-SDK介绍和选择

    转自: http://blog.csdn.net/kun1234567/article/details/10402535 ar技术序章-SDK介绍和选择 分类: Augmented Reality20 ...

  6. PAT 1012. The Best Rank

    To evaluate the performance of our first year CS majored students, we consider their grades of three ...

  7. Unity3D跨平台时partial分部方法的使用

    最近看到项目中插件的一部分逻辑,发现问题多多,可读性很差,并且容易出错,于是随手整理了下逻 辑.Unity3D的插件逻辑,因为要考虑到针对各平台的移植,因此会大片的出现#if/#endif等条件编译, ...

  8. 开源的连接池技术DBCP和C3P0

    概述: Sun公司约定: 如果是连接池技术,需要实现一个接口! javax.sql.DataSource;   相关jar包和资料下载 1.1  DBCP连接池: l  DBCP 是 Apache 软 ...

  9. text code

    https://github.com/Itseez/opencv/blob/master/modules/objdetect/src/erfilter.cpp

  10. [置顶] Linux下的截图小工具

    Linux下的截图工具scrot 基于命令行 先下载:scrot apt-get install scrot 对该工具的操作: 分为以下几个部分 1.抓取整个桌面 scrot pic.jpg 2.抓取 ...