Linux进程间通信——消息队列

消息队列是存放消息的链表,存在于内核空间,由系统内核维护

消息队列的特点:
1. 消息队列可以实现消息的随机查询,满足队列的特点但不一定要以先进先出的次序读取,可以按消息的类型读取;
2.消息队列允许一个或多个进程向它写入或者读取消息;
3.与无名管道、有名管道一样,从消息队列中读出消息,消息队列中数据会被删除;
4.消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级;
5. 只有内核重启或人工删除时,该消息才会被删除,若不人工删除消息队列,消息队列会一直存在于内存中。

消息队列标识符,来标识消息队列。消息队列在整个 系统中是唯一的。
在Linux操作系统中消息队列限制值如下:
   1. 消息队列个数最多为16个
   2. 消息队列总容量最多为16384字节
   3.每个消息内容最多为8192字节
System V提供的IPC通信机制需要一个key值,通过key 值就可在系统内获得一个唯一的消息队列。
key值可以是人为指定的,也可以通过ftok函数获得。
在这里插入图片描述

/*
   //1.创建消息队列
   int msgget(key_t key, int msgflg);
   
       msgflg: 标识函数的行为及消息队列的权限,其取值如下
         'IPC_CREAT':创建消息队列。 
         'IPC_EXCL': 检测消息队列是否存在。
    位或权限位:消息队列位或权限位后可以设置消息队列的访问权限,但可执行权限未使用。一般是0666
     返回值: 成功返回消息队列的标识符 ;失败返回
     
   //2.写入消息
    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    
        msgflg:函数的控制属性,其取值如下:
             '0': msgsnd()调用阻塞直到条件满足为止。
            'IPC_NOWAIT': 若消息没有立即发送则调用该函数的进程会立即返回。
     返回值:成功返回0,失败返回-1。
     
    //3.读取消息        
     ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
     
          msgtyp:消息的类型:
            msgtyp = 0:返回队列中的第一个消息。
            msgtyp > 0:返回队列中消息类型为 msgtyp 的消息(常用)。
            msgtyp < 0:返回队列中消息类型值小于或等于 msgtyp 绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。在获取某类型消息的时候,若队列中有多条   此类型的消息,则获取最先添加的消息,即先进先出原则。
         msgflg:函数的控制属性:
           '0': msgrcv() 调用阻塞直到接收消息成功为止。
           'MSG_NOERROR': 若返回的消息字节数比 nbytes 字节数多,则消息就会截短到 nbytes 字节,且不通知消息发送进程。
           IPC_NOWAIT: 调用进程会立即返回。若没有收到消息则立即返回 -1。
      返回值: 成功读取消息的长度; 失败:-1
      
      //4.消息队列控制
      int msgctl(int msqid, int cmd, struct msqid_ds *buf);
      
        cmd::
             'IPC_RMID' :删除消息队列。从系统中删除给消息队列以及仍在该队列上的所有数据,这种删除立即生效。仍在使用这一消息\
             队列的其他进程在它们下一次试图对此队列进行操作时,将出错,并返回EIDRM。 此命令只能由如下两种进程执行:
                1.其有效用户ID等于msg_perm.cuid或msg_perm.guid的进程。
                2.另一种是具有超级用户特权的进程。
             'IPC_SET' :设置消息队列的属性。按照buf指向的结构中的值,来设置此队列的msqid_id结构。该命令的执行特权与上一个相同。
             'IPC_STAT':读取消息队列的属性。取得此队列的msqid_ds结构,并存放在buf*中。
             'IPC_INFO':读取消息队列基本情况。
        buf:队列中的内容,一般为NULL。
*/
/*msg_send.c*/
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<string.h>


struct msgbuf{
        long mtype;//消息类型(>0)
        char mtext[128];//消息文本
};

int main()
{
        key_t key;
        struct msgbuf send = {888,"this message from send"};
        struct msgbuf getbuf;
        //获取key值
        //key_t ftok(const char *pathname, int proj_id);
        key = ftok(".",'z');//   路径          id号
        if(key == -1){
            printf("ftok error\n");
         }
        printf("key:%x\n",key);
        //创建消息队列
        int msqid = msgget(key,IPC_CREAT|0666);
        if(msqid == -1){

            printf("msg creat failed\n");
        }
        //将消息类型为'888'的信息写入队列,'0'以阻塞的方式写入
        if( msgsnd(msqid,&send,strlen(send.mtext),0) == -1){

            printf("msgsend error\n");
        }
        //从队列中读取消息类型为'666'的信息,'0',以阻塞的方式读
        msgrcv(msqid,&getbuf,128,666,0);
        printf("%s\n",getbuf.mtext);
        //删除队列
        msgctl(msqid,IPC_RMID,NULL);
        
        return 0;
 } 
/*msg_get.c*/
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf{
        long mtype;//消息类型(>0)
        char mtext[128];//消息文本
};
 
int main()
{
        key_t key;

        struct msgbuf send = {666,"this message from get"};
        struct msgbuf getbuf;

        key = ftok(".",'z');
        if(key == -1){
            printf("ftok error\n");
         }
        printf("key:%x\n",key);
        //创建消息队列
        int msqid = msgget(key,IPC_CREAT|0666);
        if(msqid == -1){

          printf("msg creat failed\n");
        }
         //获取消息类型为'888' 的消息
         msgrcv(msqid,&getbuf,128,888,0);
         printf("%s\n",getbuf.mtext);
         //发送消息类型为'666'的消息
         msgsnd(msqid,&send,strlen(send.mtext),0);
         //删除队列
         msgctl(msqid,IPC_RMID,NULL);

          return 0;
}

                         
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 了解Linux内核 1. 1 Linux内核 1. 2 查看Linux内核状况 1. 3 编程序检查系统状况 1. 4 Linux编程环境 第2章 shell 2. 1 she11 2. 2 实现一个简单的shell程序 2. 3 shell编程 第3章 内核时钟 3. 1 关于时钟和定时器 3. 2 Linux系统时钟 3. 3 Linux系统定时器 3. 4 时钟命令介绍 3. 5 定时器的应用 第4章 内核模块 4. 1 概述 4. 2 模块实现机制 4. 3 实例 第5章 系统调用 5. 1 一个简单的例子 5. 2 系统调用基础知识 5. 3 相关数据结构. 源代码分析及流程 5. 4 详细讲解一个系统调用的实现 5. 5 简单系统调用的添加 5. 6 较高级主题:添加一个更复杂的系统调用 第6章 共享内存 6. 1 进程间通信和共享内存 6. 2 共享内存的APl 6. 3 实现共享内存的源代码 6. 4 利用共享内存进行进程间通信 第7章 虚拟存储 7. 1 虚拟内存管理 7. 2 Linux虚拟内存管理 7. 3 实例 第8章 进程的同步 8. 1 同步机制 8. 2 Linux中几种同步机制的实现 8. 3 设计我们自己的同步机制 第9章 进程调度 9. 1 进程调度简介 9. 2 进程调度的策略与算法 9. 3 进程调度的实现 9. 4 改进进程调度算法的实现 第10章 设备驱动 lo. 1 Linux下驱动程序的相关概念 10. 2 传统的设备管理方式 10. 3 块设备的请求队列 lo. 4 设备文件系统devfs 10. 5 驱动程序的框架及实例分析 10. 6 设计自己的驱动程序 第11章 文件系统 11. 1 文件和目录 11. 2 文件系统的框架 11. 3 VFS文件系统 11. 4 ext2文件系统 11. 5 open. Close和read. write操作 11. 6 buffer cache 11. 7 实验:添加一个文件系统 11. 8 附录:优秀的日志文件系统--ext3

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值